fix: lock onmessage to prevent duplicate message handlers - #25
Conversation
wasm-bindgen registers a message handler during mod.default() initialization. When using addEventListener for task dispatch, both handlers fire for every postMessage, causing the wasm-bindgen handler to fail on wasmworker-format messages. Lock the onmessage setter via Object.defineProperty after init so that addEventListener remains the sole message dispatch path.
paberr
left a comment
There was a problem hiding this comment.
Thanks for the report and the fix. The placement (after mod.default(), before task dispatch, in both blobs) looks correct. Inline comments below. One more ask:
Could you add a regression test in test/, e.g., a #[wasm_bindgen(start)] fn that registers a conflicting onmessage, asserting tasks still complete?
Longer term I would move task dispatch onto a dedicated MessageChannel port, which
would make wasmworker immune to module handlers in both directions. That would be the more robust fix.
|
"This issue arose about a month ago when I was trying to integrate my own crate, draco_decoder use in project with thread pool of wasmworker i. However, the issue is quite old now, and I no longer have a code environment that can reproduce it. Moreover, I had made a series of changes to the JavaScript implementation of draco_decoder before, but those have now been reverted. Currently, I am still maintaining the worker creation on the JavaScript side of draco_decoder myself. So I'm very sorry, but this commit was also written by AI, and I'm not sure if it will be of any use." |
|
Thanks @jiangheng90. I'll have another look this week! |
The init handshake and task dispatch now run on a MessagePort transferred with the first message to the worker, leaving the worker's global message channel to the embedded module. This replaces the onmessage lock: module handlers (onmessage or addEventListener) can no longer interfere with task dispatch, and module messages posted on the global scope can no longer reach wasmworker's response callback.
paberr
left a comment
There was a problem hiding this comment.
dedicated message port looks good
Problem
wasm-bindgen's
mod.default()setsself.onmessageduring init.When wasmworker uses
addEventListener('message', ...)for task dispatch,both handlers fire. The wasm-bindgen handler cannot parse wasmworker's
message format, causing
Cannot read properties of undefined (reading 'length').Fix
Lock the
onmessagesetter viaObject.definePropertywith a no-opsetter after
mod.default()completes. Applied to bothWORKER_JSand
WORKER_JS_WITH_PRECOMPILED.Testing
Verified with 4-worker pool running mixed
#[webworker_fn]and#[webworker_channel_fn]tasks. No errors.