Skip to content

Commit 376e2a4

Browse files
robertsLandoclaude
andauthored
fix(sea): set process.pkg in worker threads (#270)
Classic (non-SEA) pkg sets process.pkg on every thread because bootstrap.js runs end-to-end in both main and worker threads. In SEA mode the worker entry only mounted the VFS and skipped setupProcessPkg, so userland helpers that gate on 'pkg' in process (a common pattern for picking process.cwd() vs __dirname when resolving runtime paths) saw undefined inside workers and routed writes into the read-only snapshot. A concrete symptom: a pino transport running in a worker thread whose target resolves a log directory through such a check would try to open a file under /snapshot/... and hang forever on the 'open' event; the main thread then surfaced the misleading "the worker has exited" error from thread-stream.writes with no real cause. Mirror the main-thread call in sea-worker-entry.js so process.pkg is populated consistently across threads, and extend the existing worker-threads SEA test to assert process.pkg.entrypoint is set inside the worker so this can't silently regress. Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
1 parent c0233e6 commit 376e2a4

4 files changed

Lines changed: 27 additions & 1 deletion

File tree

prelude/sea-worker-entry.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,17 @@
88
// TODO: Remove the node_modules/@roberts_lando/vfs patches once
99
// https://github.com/platformatic/vfs/pull/9 is merged and released.
1010

11-
require('./sea-vfs-setup');
11+
var vfs = require('./sea-vfs-setup');
12+
var shared = require('./bootstrap-shared');
13+
14+
// Mirror the main-thread setup for process.pkg so userland checks like
15+
// `'pkg' in process` / `process.pkg.entrypoint` behave consistently across
16+
// threads. In classic (non-SEA) pkg the worker bootstrap runs the same code
17+
// path as the main thread and sets this up; without it, libraries that gate
18+
// packaged-vs-filesystem logic on `process.pkg` misbehave in workers (e.g.,
19+
// a pino transport that resolves paths through such a check writes into the
20+
// read-only snapshot and hangs waiting for `open`).
21+
shared.setupProcessPkg(
22+
vfs.toPlatformPath(vfs.manifest.entrypoint),
23+
vfs.manifest.entrypoint,
24+
);

test/test-90-sea-worker-threads/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ async function main() {
4040
console.log('echo:' + result.echo);
4141
console.log('hasFilename:' + result.hasFilename);
4242
console.log('hasDirname:' + result.hasDirname);
43+
console.log('hasProcessPkg:' + result.hasProcessPkg);
4344
console.log('helperResult:' + result.helperResult);
4445
} catch (e) {
4546
console.log('worker-error:' + e.message);

test/test-90-sea-worker-threads/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const expected =
2525
'echo:ping\n' +
2626
'hasFilename:true\n' +
2727
'hasDirname:true\n' +
28+
'hasProcessPkg:true\n' +
2829
'helperResult:hello world\n';
2930

3031
utils.assertSeaOutput(testName, expected);

test/test-90-sea-worker-threads/worker.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ const { parentPort, workerData } = require('worker_threads');
66
const hasFilename = typeof __filename === 'string' && __filename.length > 0;
77
const hasDirname = typeof __dirname === 'string' && __dirname.length > 0;
88

9+
// Mirrors the main-thread compatibility contract: classic pkg sets
10+
// `process.pkg` in every thread, so any userland library that gates
11+
// behavior on `'pkg' in process` (a common pattern for picking cwd vs
12+
// __dirname when resolving runtime paths) expects this in workers too.
13+
const hasProcessPkg =
14+
typeof process.pkg === 'object' &&
15+
process.pkg !== null &&
16+
typeof process.pkg.entrypoint === 'string' &&
17+
process.pkg.entrypoint.length > 0;
18+
919
// Verify we can require a relative module from within the worker
1020
let helperResult;
1121
try {
@@ -19,5 +29,6 @@ parentPort.postMessage({
1929
echo: workerData.message,
2030
hasFilename,
2131
hasDirname,
32+
hasProcessPkg,
2233
helperResult,
2334
});

0 commit comments

Comments
 (0)