mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
fix(runtime): handle race condition in postMessage where worker has terminated (#10239)
The panic was caused by the lack of an error class mapping for futures::channel::TrySendError, but it shouldn't have been throwing an error in the first place - when a worker has terminated, postMessage should just return. The issue was that the termination message hadn't yet been recieved, so it was carrying on with trying to send the message. This adds another check on the Rust side for if the channel is closed, and if it is the worker is treated as terminated.
This commit is contained in:
parent
776a999eab
commit
4786e1d92d
4 changed files with 22 additions and 0 deletions
|
@ -2497,6 +2497,12 @@ console.log("finish");
|
|||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(nonexistent_worker {
|
||||
args: "run --allow-read workers/nonexistent_worker.ts",
|
||||
output: "workers/nonexistent_worker.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn compiler_api() {
|
||||
let status = util::deno_cmd()
|
||||
|
|
3
cli/tests/workers/nonexistent_worker.out
Normal file
3
cli/tests/workers/nonexistent_worker.out
Normal file
|
@ -0,0 +1,3 @@
|
|||
[WILDCARD]error: Uncaught (in worker "") Cannot resolve module "file:///[WILDCARD]cli/tests/workers/doesnt_exist.js".
|
||||
error: Uncaught (in promise) Error: Unhandled error event reached main worker.
|
||||
at Worker.#poll ([WILDCARD])
|
5
cli/tests/workers/nonexistent_worker.ts
Normal file
5
cli/tests/workers/nonexistent_worker.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
const w = new Worker(new URL("doesnt_exist.js", import.meta.url).href, {
|
||||
type: "module",
|
||||
});
|
||||
|
||||
w.postMessage("hello");
|
|
@ -67,6 +67,14 @@ impl WebWorkerHandle {
|
|||
/// Post message to worker as a host.
|
||||
pub fn post_message(&self, buf: Box<[u8]>) -> Result<(), AnyError> {
|
||||
let mut sender = self.sender.clone();
|
||||
// If the channel is closed,
|
||||
// the worker must have terminated but the termination message has not yet been recieved.
|
||||
//
|
||||
// Therefore just treat it as if the worker has terminated and return.
|
||||
if sender.is_closed() {
|
||||
self.terminated.store(true, Ordering::SeqCst);
|
||||
return Ok(());
|
||||
}
|
||||
sender.try_send(buf)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue