Why is insert () function splitting wrapAsync'd child_process.spawn () handlers in Meteor method?
I am trying to use child_process.spawn()
in the Meteor method. I want to grab PID, stdout, stderr and exit code from an external process and store it all in the database.
Everything worked until I added that first call insert()
. This insert()
inserts only one 'dummy' document into the database. I don't see any error messages in the server console. If I comment on the first one insert()
, the other insert()
calls will succeed.
// server/app.js
var spawn = Npm.require('child_process').spawn;
Meteor.methods({
start: function() {
var child = spawn('ls', ['/tmp']);
var pid = child.pid;
var wrappedChildStdoutOn = Meteor.wrapAsync(child.stdout.on, child.stdout);
var wrappedChildStderrOn = Meteor.wrapAsync(child.stderr.on, child.stderr);
var wrappedChildOn = Meteor.wrapAsync(child.on, child);
// this insert() breaks upcoming insert() calls!
Stuff.insert({pid: pid, date: new Date(), type: 'dummy', data: 'dummy'});
wrappedChildStdoutOn('data', function (data) {
Stuff.insert({pid: pid, date: new Date(), type: 'stdout', data: data.toString()});
});
wrappedChildStderrOn('data', function (data) {
Stuff.insert({pid: pid, date: new Date(), type: 'stderr', data: data.toString()});
});
wrappedChildOn('exit', function (code) {
Stuff.insert({pid: pid, date: new Date(), type: 'exit', code: code});
});
}
});
What happens to this first call insert()
?
source to share
insert
takes a little time, so it ls
completes its output before completion insert
. When you put the event handler in place, it's too late.
You can fix the problem, move the first insert
to the end, move the first insert
before the call, spawn
or add a no-op callback function () {}
in insert
so that it will call asynchronously.
source to share