From f97da7834728e72b2412f620eddba0dbb979a1e1 Mon Sep 17 00:00:00 2001 From: Mark Wubben Date: Sun, 20 Jun 2021 16:16:59 +0200 Subject: [PATCH] Attempt to workaround worker thread termination crash See discussion in https://github.com/nodejs/node/issues/38418 --- lib/fork.js | 7 +++++++ lib/worker/base.js | 1 + 2 files changed, 8 insertions(+) diff --git a/lib/fork.js b/lib/fork.js index ef2ecafec..f54473be4 100644 --- a/lib/fork.js +++ b/lib/fork.js @@ -3,6 +3,7 @@ import {fileURLToPath} from 'url'; import {Worker} from 'worker_threads'; import Emittery from 'emittery'; +import pEvent from 'p-event'; import {controlFlow} from './ipc-flow-control.cjs'; @@ -31,8 +32,14 @@ const createWorker = (options, execArgv) => { stderr: true }); postMessage = worker.postMessage.bind(worker); + + // Ensure we've seen this event before we terminate the worker thread, as a + // workaround for https://github.com/nodejs/node/issues/38418. + const starting = pEvent(worker, 'message', ({ava}) => ava && ava.type === 'starting'); + close = async () => { try { + await starting; await worker.terminate(); } finally { // No-op diff --git a/lib/worker/base.js b/lib/worker/base.js index 3b3eafe62..4d28447df 100644 --- a/lib/worker/base.js +++ b/lib/worker/base.js @@ -222,6 +222,7 @@ const onError = error => { }; if (isRunningInThread) { + channel.send({type: 'starting'}); // AVA won't terminate the worker thread until it's seen this message. const {options} = workerData; delete workerData.options; // Don't allow user code access. run(options).catch(onError); // eslint-disable-line promise/prefer-await-to-then