Files
codeql-action/node_modules/ava/lib/plugin-support/shared-workers.js
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

129 lines
2.9 KiB
JavaScript
Raw Normal View History

2022-02-01 18:01:11 +00:00
import events from 'node:events';
import {pathToFileURL} from 'node:url';
import {Worker} from 'node:worker_threads';
2021-10-21 15:24:20 -07:00
2022-02-01 18:01:11 +00:00
import serializeError from '../serialize-error.js';
2021-10-21 15:24:20 -07:00
2022-02-01 18:01:11 +00:00
const LOADER = new URL('shared-worker-loader.js', import.meta.url);
2021-10-21 15:24:20 -07:00
const launchedWorkers = new Map();
const waitForAvailable = async worker => {
for await (const [message] of events.on(worker, 'message')) {
if (message.type === 'available') {
return;
}
}
};
2022-02-01 18:01:11 +00:00
function launchWorker(filename, initialData) {
2021-10-21 15:24:20 -07:00
if (launchedWorkers.has(filename)) {
return launchedWorkers.get(filename);
}
const worker = new Worker(LOADER, {
// Ensure the worker crashes for unhandled rejections, rather than allowing undefined behavior.
execArgv: ['--unhandled-rejections=strict'],
workerData: {
filename,
2022-02-01 18:01:11 +00:00
initialData,
},
2021-10-21 15:24:20 -07:00
});
worker.setMaxListeners(0);
const launched = {
statePromises: {
available: waitForAvailable(worker),
2022-02-01 18:01:11 +00:00
error: events.once(worker, 'error').then(([error]) => error),
2021-10-21 15:24:20 -07:00
},
exited: false,
2022-02-01 18:01:11 +00:00
worker,
2021-10-21 15:24:20 -07:00
};
launchedWorkers.set(filename, launched);
worker.once('exit', () => {
launched.exited = true;
});
return launched;
}
2022-02-01 18:01:11 +00:00
export async function observeWorkerProcess(fork, runStatus) {
2023-01-18 20:50:03 +00:00
let signalDone;
const done = new Promise(resolve => {
signalDone = () => {
resolve();
};
2021-10-21 15:24:20 -07:00
});
2023-01-18 20:50:03 +00:00
const activeInstances = new Set();
const removeInstance = instance => {
instance.worker.unref();
activeInstances.delete(instance);
if (activeInstances.size === 0) {
signalDone();
}
};
const removeAllInstances = () => {
if (activeInstances.size === 0) {
signalDone();
return;
2021-10-21 15:24:20 -07:00
}
2023-01-18 20:50:03 +00:00
for (const instance of activeInstances) {
removeInstance(instance);
}
};
fork.promise.finally(() => {
removeAllInstances();
2021-10-21 15:24:20 -07:00
});
2022-02-01 18:01:11 +00:00
fork.onConnectSharedWorker(async ({filename, initialData, port, signalError}) => {
const launched = launchWorker(filename, initialData);
2023-01-18 20:50:03 +00:00
activeInstances.add(launched);
2021-10-21 15:24:20 -07:00
const handleWorkerMessage = async message => {
2022-02-01 18:01:11 +00:00
if (message.type === 'deregistered-test-worker' && message.id === fork.threadId) {
2021-10-21 15:24:20 -07:00
launched.worker.off('message', handleWorkerMessage);
2023-01-18 20:50:03 +00:00
removeInstance(launched);
2021-10-21 15:24:20 -07:00
}
};
2022-02-01 18:01:11 +00:00
launched.statePromises.error.then(error => {
2021-10-21 15:24:20 -07:00
launched.worker.off('message', handleWorkerMessage);
2023-01-18 20:50:03 +00:00
removeAllInstances();
2021-10-21 15:24:20 -07:00
runStatus.emitStateChange({type: 'shared-worker-error', err: serializeError('Shared worker error', true, error)});
2022-02-01 18:01:11 +00:00
signalError();
2021-10-21 15:24:20 -07:00
});
try {
await launched.statePromises.available;
2022-02-01 18:01:11 +00:00
port.postMessage({type: 'ready'});
2021-10-21 15:24:20 -07:00
launched.worker.postMessage({
type: 'register-test-worker',
2022-02-01 18:01:11 +00:00
id: fork.threadId,
file: pathToFileURL(fork.file).toString(),
port,
}, [port]);
2021-10-21 15:24:20 -07:00
fork.promise.finally(() => {
launched.worker.postMessage({
type: 'deregister-test-worker',
2022-02-01 18:01:11 +00:00
id: fork.threadId,
2021-10-21 15:24:20 -07:00
});
});
launched.worker.on('message', handleWorkerMessage);
2023-01-18 20:50:03 +00:00
} catch {}
2021-10-21 15:24:20 -07:00
});
2023-01-18 20:50:03 +00:00
return done;
2021-10-21 15:24:20 -07:00
}