Offload functions to worker threads with shared memory primitives for Node.js.
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs(serve): add highWaterMark/options docs + server-threads example

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+49
+14
README.md
··· 416 416 await listen(app.server, ...args); 417 417 ``` 418 418 419 + Options: 420 + 421 + ```ts 422 + serverThreads(run.workers, server, { 423 + balance: leastConns(), // or roundRobin(); default: leastConns() 424 + highWaterMark: 64, // per-worker cross-thread buffer (default 64) 425 + listen: { drainTimeout: 30_000 }, // per-worker drain budget on shutdown 426 + }); 427 + ``` 428 + 429 + `highWaterMark` bounds how many fds are in-transit to each worker's MessagePort at once. When a worker can't keep up, the cross-thread pipe parks until it catches up. 430 + 419 431 Graceful shutdown: call `server.close()` on the main listener; the cascade closes worker channels, drains in-flight requests (up to `drainTimeout`, default 30s), and resolves the moroutines. Combine with `await using run = workers(...)` for full pool teardown. 432 + 433 + See [`examples/server-threads`](examples/server-threads) for a runnable demo. 420 434 421 435 ## Streaming 422 436
+24
examples/server-threads/main.ts
··· 1 + // Scale an HTTP server across worker threads using fd-fanout. 2 + // Requires Node v24+ and a POSIX system (Linux, macOS). 3 + // 4 + // Run: node examples/server-threads/main.ts 5 + // Test: curl http://localhost:3000 6 + 7 + import { createServer } from 'node:net'; 8 + import { workers, assign } from '../../src/index.ts'; 9 + import { serverThreads } from '../../src/serve/index.ts'; 10 + import { runServer } from './server.ts'; 11 + 12 + const server = createServer(); 13 + server.listen(3000); 14 + 15 + process.on('SIGINT', () => server.close()); 16 + process.on('SIGTERM', () => server.close()); 17 + 18 + console.log('Listening on http://localhost:3000 with 4 worker threads'); 19 + 20 + { 21 + await using run = workers(4); 22 + using threads = serverThreads(run.workers, server); 23 + await run(threads.map(([w, args]) => assign(w, runServer(...args)))); 24 + }
+11
examples/server-threads/server.ts
··· 1 + import { createServer } from 'node:http'; 2 + import { mo } from '../../src/index.ts'; 3 + import { listen, type ListenArgs } from '../../src/serve/index.ts'; 4 + 5 + export const runServer = mo(import.meta, async (...args: ListenArgs): Promise<void> => { 6 + const srv = createServer((req, res) => { 7 + res.writeHead(200, { 'Content-Type': 'text/plain' }); 8 + res.end(`handled by worker ${process.pid}\n`); 9 + }); 10 + await listen(srv, ...args); 11 + });