Hi! I'm poking at ComponentizeJS and trying to figure out how to explicitly drop a resource. I have this code targeting WASI preview 2 HTTP working in Rust:
if let Some(body) = body {
let req_body = req.body().expect("getting body");
let stream = req_body.write().expect("getting body");
stream.blocking_write_and_flush(body).expect("writing content");
drop(stream);
OutgoingBody::finish(req_body, None).expect("finishing body");
}
As per the WIT definitions, dropping the writer is necessary before calling OutgoingBody::finish:
resource outgoing-body {
/// Returns a stream for writing the body contents.
///
/// The returned `output-stream` is a child resource: it must be dropped
/// before the parent `outgoing-body` resource is dropped (or finished),
/// otherwise the `outgoing-body` drop or `finish` will trap.
///
/// Returns success on the first call: the `output-stream` resource for
/// this `outgoing-body` may be retrieved at most once. Subsequent calls
/// will return error.
write: func() -> result<output-stream>;
However I can't figure out how to cause the drop to execute in JS:
if (body) {
let reqBody = req.body();
let stream = reqBody.write();
stream.blockingWriteAndFlush(body);
stream.drop(); // TypeError: stream.drop is not a function
OutgoingBody.finish(reqBody);
}
I know that I'm mostly on the right path, since GET methods work but my POSTs with a body are failing. Eliding the drop altogether results in the documented trap when calling OutgoingBody.finish. How can I force this stream to be dropped?
You can use stream[Symbol.for('dispose')]();
to do the dispose from JS
And of course 5 minutes after posting that I find: https://github.com/bytecodealliance/ComponentizeJS/blob/89ac2c5730866ebe47afaf3a8ae231c59761796e/test/cases/resource-borrow-import/source.js#L3
I had tried with Symbol.dispose
previously and that didn't work, so apparently the magic was Symbol.for('dispose')
When Spidermonkey supports Symbol.dispose
we will switch to that
so then it will be the new using
syntax eventually
we should better document this though certainly
Right, and I suppose if I had adopted typescript's using then I wouldn't have seen this at all
While you're active - is there a recommended bundler for joining multiple JS files together? I just want to unclutter my main file by putting some helpers somewhere else, but naive concat quickly runs into import collisions
preferably something invokeable from the mjs file
Note it's still Symbol.for('dispose')
instead of Symbol.dispose
. We could directly define Symbol.dispose = Symbol.for('dispose')
to make this easier I suppose, posted https://github.com/bytecodealliance/ComponentizeJS/pull/81. For bundling modules, esbuild / swc / rollup are all good.
oh nice! that looks great
Chad Kimes has marked this topic as resolved.
Last updated: Dec 23 2024 at 12:05 UTC