Skip to content

Commit 9086338

Browse files
ErickWendeldanielleadams
authored andcommittedFeb 1, 2022
child_process: queue pending messages
It fixes the problem of the child process not receiving messages. Fixes: #41134 PR-URL: #41221 Reviewed-By: Adrian Estrada <edsadr@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
1 parent 256bf9e commit 9086338

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed
 

‎lib/internal/child_process.js

+29-1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ let HTTPParser;
8181
const MAX_HANDLE_RETRANSMISSIONS = 3;
8282
const kChannelHandle = Symbol('kChannelHandle');
8383
const kIsUsedAsStdio = Symbol('kIsUsedAsStdio');
84+
const kPendingMessages = Symbol('kPendingMessages');
8485

8586
// This object contain function to convert TCP objects to native handle objects
8687
// and back again.
@@ -528,6 +529,7 @@ class Control extends EventEmitter {
528529
constructor(channel) {
529530
super();
530531
this.#channel = channel;
532+
this[kPendingMessages] = [];
531533
}
532534

533535
// The methods keeping track of the counter are being used to track the
@@ -701,6 +703,24 @@ function setupChannel(target, channel, serializationMode) {
701703
});
702704
});
703705

706+
target.on('newListener', function() {
707+
708+
process.nextTick(() => {
709+
if (!target.channel || !target.listenerCount('message'))
710+
return;
711+
712+
const messages = target.channel[kPendingMessages];
713+
const { length } = messages;
714+
if (!length) return;
715+
716+
for (let i = 0; i < length; i++) {
717+
ReflectApply(target.emit, target, messages[i]);
718+
}
719+
720+
target.channel[kPendingMessages] = [];
721+
});
722+
});
723+
704724
target.send = function(message, handle, options, callback) {
705725
if (typeof handle === 'function') {
706726
callback = handle;
@@ -914,7 +934,15 @@ function setupChannel(target, channel, serializationMode) {
914934
};
915935

916936
function emit(event, message, handle) {
917-
target.emit(event, message, handle);
937+
if ('internalMessage' === event || target.listenerCount('message')) {
938+
target.emit(event, message, handle);
939+
return;
940+
}
941+
942+
ArrayPrototypePush(
943+
target.channel[kPendingMessages],
944+
[event, message, handle]
945+
);
918946
}
919947

920948
function handleMessage(message, handle, internal) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import '../common/index.mjs';
2+
import assert from 'assert';
3+
import { fork } from 'child_process';
4+
import { once } from 'events';
5+
import { fileURLToPath } from 'url';
6+
7+
if (process.argv[2] !== 'child') {
8+
const filename = fileURLToPath(import.meta.url);
9+
const cp = fork(filename, ['child']);
10+
const message = 'Hello World';
11+
cp.send(message);
12+
13+
const [received] = await once(cp, 'message');
14+
assert.deepStrictEqual(received, message);
15+
16+
cp.disconnect();
17+
await once(cp, 'exit');
18+
} else {
19+
process.on('message', (msg) => process.send(msg));
20+
}

0 commit comments

Comments
 (0)
Please sign in to comment.