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.

fix(serve): use /proc/self/fd on Linux for fd dup

/dev/fd is not available on all Linux distros (notably NixOS).
Use /proc/self/fd on Linux, /dev/fd on macOS.

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

+12 -3
+4 -1
src/serve/server-threads.ts
··· 1 1 import { closeSync, openSync } from 'node:fs'; 2 + import { platform } from 'node:process'; 2 3 import type { Server } from 'node:net'; 4 + 5 + const fdPath = (fd: number) => (platform === 'linux' ? `/proc/self/fd/${fd}` : `/dev/fd/${fd}`); 3 6 import { channel } from '../channel.ts'; 4 7 import { shared } from '../shared/shared.ts'; 5 8 import { int32atomic } from '../shared/descriptors.ts'; ··· 50 53 // event loop tracking. This lets socket.destroy() properly close the 51 54 // original fd (freeing libuv state) while the dup'd fd survives for the 52 55 // worker to open as a fresh Socket. 53 - const fd = openSync(`/dev/fd/${origFd}`, 'r+'); 56 + const fd = openSync(fdPath(origFd), 'r+'); 54 57 socket.destroy(); 55 58 56 59 counters.elements[idx].add(1);
+4 -1
test/serve/listen.test.ts
··· 2 2 import assert from 'node:assert/strict'; 3 3 import { once } from 'node:events'; 4 4 import { openSync } from 'node:fs'; 5 + import { platform } from 'node:process'; 5 6 import { createServer as createNetServer, connect } from 'node:net'; 7 + 8 + const fdPath = (fd: number) => (platform === 'linux' ? `/proc/self/fd/${fd}` : `/dev/fd/${fd}`); 6 9 import { createServer } from 'node:http'; 7 10 import { int32atomic } from 'moroutine'; 8 11 import { Int32Atomic } from '../../src/shared/int32-atomic.ts'; ··· 20 23 const client = connect(port); 21 24 const [peer] = (await once(srv, 'connection')) as [any]; 22 25 const origFd: number = peer._handle.fd; 23 - const fd = openSync(`/dev/fd/${origFd}`, 'r+'); // dup — new fd, not tracked by libuv 26 + const fd = openSync(fdPath(origFd), 'r+'); // dup — new fd, not tracked by libuv 24 27 peer.pause(); 25 28 peer._handle = null; 26 29 peer.destroy();
+4 -1
test/serve/spike.test.ts
··· 2 2 import assert from 'node:assert/strict'; 3 3 import { once } from 'node:events'; 4 4 import { openSync } from 'node:fs'; 5 + import { platform } from 'node:process'; 5 6 import { createServer, connect } from 'node:net'; 7 + 8 + const fdPath = (fd: number) => (platform === 'linux' ? `/proc/self/fd/${fd}` : `/dev/fd/${fd}`); 6 9 import { Worker } from 'node:worker_threads'; 7 10 8 11 describe('fd-passing spike', () => { ··· 24 27 const server = createServer(); 25 28 server.on('connection', (socket) => { 26 29 // Dup the fd via /dev/fd so the new descriptor is independent of libuv. 27 - const fd = openSync(`/dev/fd/${(socket as any)._handle.fd}`, 'r+'); 30 + const fd = openSync(fdPath((socket as any)._handle.fd), 'r+'); 28 31 socket.destroy(); 29 32 worker.postMessage({ fd }); 30 33 });