Wenn der stdout eines untergeordneten Prozesses als stdin für einen anderen verwendet wird, werden Daten manchmal nicht an das nächste untergeordnete Element übergeben:Daten werden manchmal nicht an den zweiten untergeordneten Prozess übergeben, wenn der stdout eines untergeordneten Prozesses als Stdin eines anderen verwendet wird
var spawn = require('child_process').spawn;
var pipeId = 0;
var launchProcess = function(cmd, args, stdin){
return spawn(cmd, args, {
stdio: [stdin ? stdin : 'ignore', 'pipe', 'pipe']
});
};
var launch = function(){
var task0 = launchProcess('echo', ['how\nare\nyou\ndear\nstranger']);
var task1 = launchProcess('tee', ['/tmp/body-pipeline-' + pipeId], task0.stdout);
pipeId++;
task1.on('exit', launch);
};
launch();
Einige Dateien sind leer:
ls -lhS /tmp/body-pipeline-*
ich versuchte auch, als eine positive ganze Zahl mit dem Dateideskriptor vorbei task0.stdout._handle.fd
Zugriff auf und das Problem weiterhin besteht.
So funktioniert Shell-Pipes meines Wissens: Derselbe Dateideskriptor für die Standardausgabe eines Prozesses wird als Standard einer anderen verwendet. Ich versuche zu vermeiden, alle Daten über den NodeJS-Prozess zu übergeben, da es hohe CPU-Lasten verursacht, wenn die untergeordneten Prozesse viele Daten ausgeben.
aktualisieren: Bei Rohrleitungen für beiden stdin verwendet werden und stdout alles wie erwartet funktioniert (hier mit Katze mit längerem Text zu testen):
var spawn = require('child_process').spawn;
var pipeId = 0;
var launchProcess = function(cmd, args, stdin){
return spawn(cmd, args, {
stdio: [stdin ? stdin : 'pipe', 'pipe', 'pipe']
});
};
var launch = function(){
var task0 = launchProcess('cat');
var task1 = launchProcess('tee', ['/tmp/body-pipeline-' + pipeId]);
task0.stdout.pipe(task1.stdin)
task0.stdin.write(JSON.stringify(process.env).split(',').join('\n'))
task0.stdin.end();
pipeId++;
task1.on('exit', launch);
};
launch();
Update2: Wenn task0.stdout.pipe(task1.stdin)
das Skript verwendet 50 % CPU (im Vergleich zu 0% bei der Übergabe von stdout Task0 als stdin von task1):
var spawn = require('child_process').spawn;
var pipeId = 0;
var launchProcess = function(cmd, args, stdin, stdout, stderr){
return spawn(cmd, args, {
stdio: [stdin, stdout, stderr]
});
};
var launch = function(){
var task0 = launchProcess('yes', ['lala'], 'ignore', 'pipe', 'ignore');
var task1 = launchProcess('tee', ['/tmp/body-pipeline-' + pipeId], 'pipe', 'ignore', 'ignore');
// var task1 = launchProcess('tee', ['/tmp/body-pipeline-' + pipeId], task0.stdout, 'ignore', 'ignore');
task0.stdout.pipe(task1.stdin);
pipeId++;
task1.on('exit', launch);
};
launch();
Update3: Das veranschaulicht mein Problem besser. Ich habe versucht, es im ursprünglichen Code zu vereinfachen, aber ich denke, es war zu vereinfacht. Larry Turtis bot eine Lösung für den vereinfachten Fall, aber das gilt nicht für die Mine:
var spawn = require('child_process').spawn;
var pipeId = 0;
var pipeSlots = 6;
var launchProcess = function(cmd, args, stdin, stdout){
return spawn(cmd, args, {
stdio: [stdin, stdout, 'ignore']
});
};
var launch = function(){
var task0 = launchProcess('echo', ['how\nare\nyou\ndear\nstranger'], 'ignore', 'pipe');
var task1 = launchProcess('tee', ['/tmp/body-pipeline-' + pipeId], task0.stdout, 'ignore');
task0.on('error', function(err){
console.log('Error while processing task0:' + err.stack);
});
task1.on('error', function(err){
console.log('Error while processing task1:' + err.stack);
});
pipeId++;
};
// Simulating message queue
setInterval(function(){
// Simulating how many messages we get from the messaging queue
var mqMessageCount = Math.floor(Math.random() * (pipeSlots + 1));
for(var i = 0; i < mqMessageCount; i++){
launch();
}
}, 250); // For this test we assume that pipes finish under 250ms
Tipp: Sie sollten fast immer das "close" -Ereignis des Child-Prozesses anstelle von "exit" verwenden, da ersteres anzeigt, dass auf stdout/stderr keine Daten mehr verfügbar sind. "close" kommt immer nach "exit". – mscdex
@mscdex Danke für die Information! Das Erstellen eines neuen Prozesses sollte kein unterschiedliches Verhalten haben, abhängig davon, ob andere Spawn-Prozesse ausgeführt oder beendet werden. –