"stdio: ['ipc']" not documented in fibjs website and child_process.send() works only in this 'ipc' case
forchid opened this issue · 1 comments
forchid commented
I try to build a application that has communication between parent-child processes by child_process
module, Error: [20009] Invalid procedure call
raised and this child process property connected is false when calling a child process send()
method. In nodejs website, I see the 'ipc' stdio option, it works both fibjs and nodejs, but it not documented in fibjs website.
Test case
// multi-process-test.js
const child_process = require('child_process');
const net = require('net');
const path = require('path');
const fibjs = 'fibjs' === process.argv[0];
let co = null;
if (fibjs) co = require('coroutine');
const chPath = path.join(__dirname, 'so-child-process.js');
const cmd = co? 'fibjs': 'node';
// 1)child process connected false!
const child = child_process.spawn(cmd, [chPath], { stdio: 'pipe'/*default*/ });
// 2)child process connected false!
//const child = child_process.spawn(cmd, [chPath], { stdio: 'ignore' });
// 3)child process connected false!
//const child = child_process.spawn(cmd, [chPath], { stdio: 'inherit' });
// OK! But 'ipc' not documented in fibjs website!
//const child = child_process.spawn(cmd, [chPath], { stdio: ['ipc'] });
child.on('exit', exit);
if (co) {
while(!child.connected) {
console.log('Parent: wait for parent-child pipe conn, current %s',
child.connected);
try {
child.send({ cmd: 'test' });
} catch (e) {
console.log('Parent: send() failed when child not connected - ' + e);
}
co.sleep(1000);
}
console.log('Parent: connected to child? %s', child.connected);
console.log('Parent: >> start');
child.send({ cmd: 'start' });
} else {
let timer = setInterval(() => {
if (!child.connected) {
console.log('Parent: wait for parent-child pipe conn, current %s',
child.connected);
} else {
console.log('Parent: connected to child? %s', child.connected);
console.log('Parent: >> start');
child.send({ cmd: 'start' });
clearInterval(timer);
}
}, 1000);
}
child.on('message', m => {
console.log('Parent: << %s', m.msg);
switch (m.msg) {
case 'Ok':
ping();
break;
case 'Pong':
console.log('Parent: >> exit');
child.send({ cmd: 'exit' });
break;
case 'Bye':
break;
default:
break;
}
});
function exit() {
if (fibjs) child.join();
console.log('Parent: child exit code %s', child.exitCode);
console.log('Parent: parent also exit');
process.exit(0);
}
function ping() {
console.log('Parent: >> ping');
child.send({ cmd: 'ping' });
}
// so-child-process.js
const fibjs = 'fibjs' == process.argv[0];
let co = null;
if (fibjs) co = require('coroutine');
process.on('message', (m) => {
console.log('soc: << %s', JSON.stringify(m));
switch (m.cmd) {
case 'start':
process.send({ msg: 'child starting ..' });
init();
break;
case 'ping':
process.send({ msg: 'Pong' });
break;
case 'exit':
process.send({ msg: 'Bye' });
process.exit(0);
default:
process.send(m);
break;
}
});
function init() {
process.send({ msg: 'Ok' });
}
if (fibjs) {
do {
console.log('Child: wait for parent-child pipe conn, current %s',
process.connected);
co.sleep(1000);
} while (!process.connected);
} else {
let timer = setInterval(() => {
if (!process.connected) {
console.log('Child: wait for parent-child pipe conn, current %s',
process.connected);
} else {
clearInterval(timer);
}
}, 1000);
}
>fibjs multi-process-test.js
Parent: wait for parent-child pipe conn, current false
Parent: send() failed when child not connected - Error: [20009] Invalid procedure call.
Parent: wait for parent-child pipe conn, current false
Parent: send() failed when child not connected - Error: [20009] Invalid procedure call.
Parent: wait for parent-child pipe conn, current false
Parent: send() failed when child not connected - Error: [20009] Invalid procedure call.
Parent: wait for parent-child pipe conn, current false
Parent: send() failed when child not connected - Error: [20009] Invalid procedure call.
xicilion commented
ipc channels are only supported in child processes of child_process.fork, just modify this line:
const child = child_process.fork([chPath]);