Offload functions to worker threads with shared memory primitives for Node.js.
1import { describe, it } from 'node:test';
2import assert from 'node:assert/strict';
3import { workers } from 'moroutine';
4import { makeCtx, makeMultiplierCtx, readCtx, addWithCtx, prefixValue } from './fixtures/context.ts';
5
6describe('task-arg caching', () => {
7 it('task arg is resolved on the worker', async () => {
8 const ctx = makeCtx('hello');
9 const run = workers(1);
10 try {
11 const result = await run(readCtx(ctx));
12 assert.equal(result.value, 'hello');
13 } finally {
14 run[Symbol.dispose]();
15 }
16 });
17
18 it('task arg is cached — same task evaluated once per worker', async () => {
19 const ctx = makeCtx('test');
20 const run = workers(1);
21 try {
22 const r1 = await run(readCtx(ctx));
23 const r2 = await run(readCtx(ctx));
24 // Same workerInitId means ctx was only evaluated once
25 assert.equal(r1.workerInitId, r2.workerInitId);
26 assert.equal(r1.value, 'test');
27 } finally {
28 run[Symbol.dispose]();
29 }
30 });
31
32 it('different workers each evaluate the task independently', async () => {
33 const ctx = makeCtx('test');
34 const run = workers(2);
35 try {
36 const r1 = await run(readCtx(ctx));
37 const r2 = await run(readCtx(ctx));
38 // Each worker's initCount starts at 0, so both get workerInitId=1
39 assert.equal(r1.workerInitId, 1);
40 assert.equal(r2.workerInitId, 1);
41 } finally {
42 run[Symbol.dispose]();
43 }
44 });
45
46 it('task arg works alongside regular args', async () => {
47 const ctx = makeMultiplierCtx(3);
48 const run = workers(1);
49 try {
50 const result = await run(addWithCtx(ctx, 2, 5));
51 assert.equal(result, 21); // (2 + 5) * 3
52 } finally {
53 run[Symbol.dispose]();
54 }
55 });
56
57 it('nested task args resolve recursively', async () => {
58 // makeCtx('hello') is a task-arg passed to prefixValue
59 // prefixValue itself is the outer task dispatched to the worker
60 // The worker must resolve makeCtx first, then call prefixValue with the result
61 const ctx = makeCtx('hello');
62 const run = workers(1);
63 try {
64 const result = await run(prefixValue(ctx, '>>> '));
65 assert.equal(result, '>>> hello');
66 } finally {
67 run[Symbol.dispose]();
68 }
69 });
70});