-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(workers): Don't panic when a worker's parent thread stops running #12156
fix(workers): Don't panic when a worker's parent thread stops running #12156
Conversation
As it turns out, terminating the worker when
|
This panic could happen in the following cases: - A non-fatal error being thrown from a worker, that doesn't terminate the worker's execution, but propagates to the main thread without being handled, and makes the main thread terminate. - A nested worker being alive while its parent worker gets terminated. - A race condition if the main event loop terminates the worker as part of its last task, but the worker doesn't fully terminate before the main event loop stops running. This panic happens because a worker's event loop should have pending ops as long as the worker isn't closed or terminated – but if an event loop finishes running while it has living workers, its associated `WorkerThread` structs will be dropped, closing the channels that keep those ops pending. This change adds a `Drop` implementation to `WorkerThread`, which terminates the worker without waiting for a response. This fixes the panic, and makes it so nested workers are automatically terminated once any of their ancestors is closed or terminated. This change also refactors a worker's termination code into a `WorkerThread::terminate()` method. Closes denoland#11342.
6cd79db
to
e20dd13
Compare
WebWorkerHandle
should terminate the workerThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, let's try this
.expect("Worker thread panicked") | ||
.expect("Panic in worker event loop"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if we should be expect()
ing here. This would cause another panic if something goes wrong in worker and might be prone to other race conditions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although that doesn't change current behavior so I guess it's fine for now
Before denoland#12156, closing a worker which had children would cause a panic (denoland#11342 (comment)). After that PR, closing a worker will also close any child workers.
…12215) Before #12156, closing a worker which had children would cause a panic (#11342 (comment)). After that PR, closing a worker will also close any child workers.
…denoland#12156) This panic could happen in the following cases: - A non-fatal error being thrown from a worker, that doesn't terminate the worker's execution, but propagates to the main thread without being handled, and makes the main thread terminate. - A nested worker being alive while its parent worker gets terminated. - A race condition if the main event loop terminates the worker as part of its last task, but the worker doesn't fully terminate before the main event loop stops running. This panic happens because a worker's event loop should have pending ops as long as the worker isn't closed or terminated – but if an event loop finishes running while it has living workers, its associated `WorkerThread` structs will be dropped, closing the channels that keep those ops pending. This change adds a `Drop` implementation to `WorkerThread`, which terminates the worker without waiting for a response. This fixes the panic, and makes it so nested workers are automatically terminated once any of their ancestors is closed or terminated. This change also refactors a worker's termination code into a `WorkerThread::terminate()` method. Closes denoland#11342. Co-authored-by: Bartek Iwańczuk <[email protected]>
This panic could happen in the following cases:
This panic happens because a worker's event loop should have pending ops as long as the worker isn't closed or terminated – but if an event loop finishes running while it has living workers, its associated
WorkerThread
structs will be dropped, closing the channels that keep those ops pending.This change adds a
Drop
implementation toWorkerThread
, which terminates the worker without waiting for a response. This fixes the panic, and makes it so nested workers are automatically terminated once any of their ancestors is closed or terminated.This change also refactors a worker's termination code into a
WorkerThread::terminate()
method.Closes #11342.