worker: flush stdout and stderr on exit

Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/56428
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
pull/56113/merge
Matteo Collina 2025-01-06 02:22:27 -05:00 committed by GitHub
parent b736028c7f
commit b0c65bbe8a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 68 additions and 4 deletions

View File

@ -33,11 +33,22 @@ process.removeListener('removeListener', stopListeningIfSignal);
const {
createWorkerStdio,
kStdioWantsMoreDataCallback,
} = require('internal/worker/io');
let workerStdio;
function lazyWorkerStdio() {
return workerStdio ??= createWorkerStdio();
if (workerStdio === undefined) {
workerStdio = createWorkerStdio();
process.on('exit', flushSync);
}
return workerStdio;
}
function flushSync() {
workerStdio.stdout[kStdioWantsMoreDataCallback]();
workerStdio.stderr[kStdioWantsMoreDataCallback]();
}
function getStdout() { return lazyWorkerStdio().stdout; }

View File

@ -292,9 +292,13 @@ class WritableWorkerStdio extends Writable {
chunks: ArrayPrototypeMap(chunks,
({ chunk, encoding }) => ({ chunk, encoding })),
});
ArrayPrototypePush(this[kWritableCallbacks], cb);
if (this[kPort][kWaitingStreams]++ === 0)
this[kPort].ref();
if (process._exiting) {
cb();
} else {
ArrayPrototypePush(this[kWritableCallbacks], cb);
if (this[kPort][kWaitingStreams]++ === 0)
this[kPort].ref();
}
}
_final(cb) {

View File

@ -0,0 +1,24 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { Worker, isMainThread } = require('worker_threads');
if (isMainThread) {
const w = new Worker(__filename, { stdout: true });
const expected = 'hello world';
let data = '';
w.stdout.setEncoding('utf8');
w.stdout.on('data', (chunk) => {
data += chunk;
});
w.on('exit', common.mustCall(() => {
assert.strictEqual(data, expected);
}));
} else {
process.stdout.write('hello');
process.stdout.write(' ');
process.stdout.write('world');
process.exit(0);
}

View File

@ -0,0 +1,25 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { Worker, isMainThread } = require('worker_threads');
if (isMainThread) {
const w = new Worker(__filename, { stdout: true });
const expected = 'hello world';
let data = '';
w.stdout.setEncoding('utf8');
w.stdout.on('data', (chunk) => {
data += chunk;
});
w.on('exit', common.mustCall(() => {
assert.strictEqual(data, expected);
}));
} else {
process.on('exit', () => {
process.stdout.write(' ');
process.stdout.write('world');
});
process.stdout.write('hello');
}