-
-
Notifications
You must be signed in to change notification settings - Fork 31
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
feat: terminateTimeout
option
#50
Conversation
|
||
const timer = timeout | ||
? setTimeout( | ||
() => reject(new Error('Failed to terminate worker')), |
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.
One idea I had was that here we could tell the worker to process.exit
if main thread's worker.terminate
was taking too long or got stuck.
setTimeout(() => {
this.worker.postMessage('TERMINATE_NOW')
reject(new Error('Failed to terminate worker')
})
Worker would catch this:
// worker.ts
parentPort.on('message', (message) => {
// Main thread tried to terminate this worker but failed, let's force the exit here in worker
if (message === 'TERMINATE_NOW') {
process.exit()
}
})
But it seems that this does not work. The worker never receives the message. I guess the worker.terminate()
has already closed the message channel even though it has not yet resolved completely.
4a96fc8
to
f8a2899
Compare
) | ||
: null | ||
|
||
this.worker.terminate().then(() => { |
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.
can't we just await the terminate instead of using the then keyword? if not, why?
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.
We cannot await
as the outer Promise has to be the return value.
This outer Promise is required since setTimeout
is used to decide when destroy
function should reject. This would not work:
async function destroy() {
setTimeout(() => {
throw new Error("Timeout error")
}, 1000);
await sleep(2000);
}
destroy().then(() => console.log("success")).catch(() => console.log("Failed"))
> Uncaught Error: Timeout error
> success
Wrapping everything in a outer Promise helps:
async function destroy() {
let resolve, reject;
const outerPromise = new Promise((res, rej) => {
resolve = res
reject = rej
})
setTimeout(() => {
reject(new Error("Timeout error"))
}, 1000);
sleep(2000).then(resolve);
return outerPromise;
}
destroy().then(() => console.log("success")).catch(() => console.log("Failed"))
> Failed
Similar pattern is used in runTask
:
Lines 832 to 838 in d5e5738
let resolve: (result: any) => void | |
let reject: (err: Error) => void | |
// eslint-disable-next-line | |
const ret = new Promise((res, rej) => { | |
resolve = res | |
reject = rej | |
}) |
Thank you so much @AriPerkkio, let's merge this. |
terminateTimeout
options that decides when slow/stuck worker termination should be error #49Example usage: