Offload functions to worker threads with shared memory primitives for Node.js.
1// Worker affinity via a custom balancer + isTask().
2//
3// Each worker keeps its own in-memory counter map. The keyAffinity balancer
4// uses isTask() to inspect a task's args and route by a consistent hash of
5// the key, so successive operations on the same key always hit the worker
6// that already has that key's state.
7//
8// Requires Node v24+.
9// Run: node examples/worker-affinity/main.ts
10
11import { workers, roundRobin } from '../../src/index.ts';
12import type { Balancer } from '../../src/index.ts';
13import { increment, read } from './counter.ts';
14import { keyAffinity } from './key-affinity.ts';
15
16const operations = [
17 ['a', 1],
18 ['b', 1],
19 ['a', 2],
20 ['c', 1],
21 ['b', 3],
22 ['a', 1],
23 ['c', 4],
24 ['b', 1],
25] as const;
26const expected = { a: 4, b: 5, c: 5 };
27
28async function demo(label: string, balance: Balancer) {
29 using run = workers(4, { balance });
30 await run(operations.map(([k, n]) => increment(k, n)));
31 const [a, b, c] = await run([read('a'), read('b'), read('c')]);
32 const got = { a, b, c };
33 const ok = got.a === expected.a && got.b === expected.b && got.c === expected.c;
34 console.log(`${label.padEnd(16)} got=${JSON.stringify(got)} ${ok ? 'OK' : 'WRONG (counts split across workers)'}`);
35}
36
37await demo('round-robin', roundRobin());
38await demo('keyAffinity()', keyAffinity());