mirror of
https://github.com/nodejs/node.git
synced 2025-04-30 23:56:58 +00:00

When a Worker is terminated, its own handle and the public `MessagePort` are `.ref()`’ed, so that all relevant events, including the `'exit'` events, end up being received. However, this is problematic if messages end up being queued from the Worker between the beginning of the `.terminate()` call and its completion, and there are no `'message'` event handlers present at that time. In that situation, currently the messages would not end up being processed, and since the MessagePort is still `.ref()`’ed, it would keep the event loop alive indefinitely. To fix this: - Make sure that all messages end up being received by `drainMessagePort()`, including cases in which the port had been stopped (i.e. there are no `'message'` listeners) and cases in which we exceed the limit for messages being processed in one batch. - Unref the Worker’s internal ports manually after the Worker has exited. Either of these solutions should be solving this on its own, but I think it makes sense to make sure that both of them happen during cleanup. PR-URL: https://github.com/nodejs/node/pull/37319 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
13 lines
415 B
JavaScript
13 lines
415 B
JavaScript
'use strict';
|
||
const common = require('../common');
|
||
const { Worker } = require('worker_threads');
|
||
|
||
// The actual test here is that the Worker does not keep the main thread
|
||
// running after it has been .terminate()’ed.
|
||
|
||
const w = new Worker(`
|
||
const p = require('worker_threads').parentPort;
|
||
while(true) p.postMessage({})`, { eval: true });
|
||
w.once('message', () => w.terminate());
|
||
w.once('exit', common.mustCall());
|