UNPKG

@jonahsnider/benchmark

Version:

A Node.js benchmarking library with support for multithreading and TurboFan optimization isolation.

69 lines 3.81 kB
var _Thread_instances, _Thread_worker, _Thread_workerOptions, _Thread_createWorker, _Thread_onExit, _Thread_onAbort; import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; import assert from 'node:assert/strict'; import { once } from 'node:events'; import { Worker } from 'node:worker_threads'; import { Suite } from './suite.js'; import { ThreadWorker } from './types/index.js'; import { compatibleImport } from './utils.js'; const WORKER_PATH = new URL('thread-worker.js', import.meta.url); /** * Runs a {@link (Suite:class)} in a separate thread. */ export class Thread { static async init(suiteFilepath) { const suite = await compatibleImport(suiteFilepath); assert.ok(suite instanceof Suite, new TypeError(`Expected "${suiteFilepath}" to export a Suite instance`)); return new Thread(suite, suiteFilepath); } constructor(suite, suitePath) { _Thread_instances.add(this); _Thread_worker.set(this, void 0); _Thread_workerOptions.set(this, void 0); this.name = suite.name; this.filepath = suitePath; const workerData = { suitePath, }; __classPrivateFieldSet(this, _Thread_workerOptions, { workerData, }, "f"); __classPrivateFieldSet(this, _Thread_worker, __classPrivateFieldGet(this, _Thread_instances, "m", _Thread_createWorker).call(this), "f"); __classPrivateFieldGet(this, _Thread_worker, "f").on('exit', __classPrivateFieldGet(this, _Thread_instances, "m", _Thread_onExit).bind(this)); __classPrivateFieldGet(this, _Thread_worker, "f").unref(); } async run(abortSignal) { const runMessage = { kind: ThreadWorker.Message.Kind.Run }; // Worker must be run before an abort signal is sent __classPrivateFieldGet(this, _Thread_worker, "f").postMessage(runMessage); const onAbortListener = __classPrivateFieldGet(this, _Thread_instances, "m", _Thread_onAbort).bind(this); abortSignal?.addEventListener('abort', onAbortListener, { once: true }); const message = once(__classPrivateFieldGet(this, _Thread_worker, "f"), 'message').finally(() => abortSignal?.removeEventListener('abort', onAbortListener)); const [response] = (await message); switch (response.kind) { case ThreadWorker.Response.Kind.Results: { return response.results; } case ThreadWorker.Response.Kind.Error: { // Note: Structured clone algorithm has weird behavior with Error instances - see https://github.com/nodejs/help/issues/1558#issuecomment-431142715 and https://github.com/nodejs/node/issues/26692#issuecomment-658010376 throw response.error; } default: { throw new RangeError(`Unknown response kind`); } } } } _Thread_worker = new WeakMap(), _Thread_workerOptions = new WeakMap(), _Thread_instances = new WeakSet(), _Thread_createWorker = function _Thread_createWorker() { return new Worker(WORKER_PATH, __classPrivateFieldGet(this, _Thread_workerOptions, "f")); }, _Thread_onExit = async function _Thread_onExit(code) { // This prevents the main thread from hanging when the worker is not `unref`'d await __classPrivateFieldGet(this, _Thread_worker, "f").terminate(); // Create a new worker __classPrivateFieldSet(this, _Thread_worker, __classPrivateFieldGet(this, _Thread_instances, "m", _Thread_createWorker).call(this), "f"); throw new Error(`Worker exited with code ${code}`); }, _Thread_onAbort = function _Thread_onAbort() { const abortMessage = { kind: ThreadWorker.Message.Kind.Abort }; __classPrivateFieldGet(this, _Thread_worker, "f").postMessage(abortMessage); }; //# sourceMappingURL=thread.js.map