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>