Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions js/worker-threads/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -781,10 +781,13 @@ describe("WorkerThreads", () => {
}
);

it("retries a task once when its reused thread dies before starting it", async () => {
it("retries a task once when its reused thread dies before starting it", async ({
onTestFinished,
}) => {
const executor = new WorkerThreads({ maxThreads: 1 });
onTestFinished(() => executor.close());
const exiting = executor.handler(testJob, {
exportName: "blockThenExit",
exportName: "exitBeforeNextTask",
module: handlers,
});
const complete = executor.handler(testJob, {
Expand All @@ -805,7 +808,6 @@ describe("WorkerThreads", () => {
crashedThreads: 1,
totalThreads: 1,
});
await executor.close();
});

it("fails an attempt that exceeds its thread's heap limit", async () => {
Expand Down
23 changes: 10 additions & 13 deletions js/worker-threads/src/testdata/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* the TypeScript source, so every test also exercises the thread's fallback
* from a missing `.js` module to its `.ts` source.
*/
import { parentPort } from "node:worker_threads";

import {
complete as completeOutcome,
snooze as snoozeOutcome,
Expand All @@ -22,19 +24,6 @@ export const allocateForever: TestHandler = ({ logger }) => {
for (;;) retained.push(new Array<number>(100_000).fill(retained.length));
};

export const blockThenExit: TestHandler = () => {
// Keep the thread busy after returning so the next run message is queued
// behind this callback, then exit before the thread can acknowledge it.
setImmediate(() => {
const end = Date.now() + 100;
while (Date.now() < end) {
// Deliberately block this isolated thread.
}
process.exit(9);
});
return completeOutcome();
};

export const complete: TestHandler = ({ job }) =>
completeOutcome({ output: { value: job.args.value ?? null } });

Expand Down Expand Up @@ -93,6 +82,14 @@ export const echoExact: TestHandler = ({
return completeOutcome({ output: { id } });
};

export const exitBeforeNextTask: TestHandler = () => {
// Replace the run listener so the next task kills this thread before it
// can acknowledge the task. A setImmediate callback races with that message.
parentPort?.removeAllListeners("message");
parentPort?.once("message", () => process.exit(9));
return completeOutcome();
};

export const exitWhenIdle: TestHandler = () => {
setImmediate(() => process.exit(7));
return completeOutcome();
Expand Down
Loading