I'm writing a Meteor app that executes several shell commands on the server. I want realtime output from the server to the client, but I'm having trouble figuring out the realtime part. I do not want to wait for the command to finish - since it might take a long time.
For now I have created a Logs Mongo collection to store the output in. But I am getting errors like this: "Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment."
It sounds like I Meteor wants me to wait until all the output is done writing. I dont want to wrapAsync because I want the async output printed on the client side as it comes line by line. Spawn returns a stream on the server so that side is covered, I'm just having trouble streaming to the client. Here is an example:
Logs = new Mongo.Collection("logs");
if (Meteor.isClient) {
Template.body.helpers({
log: function(branchName) {
return Logs.find({});
}
});
Template.branch.events({
'click button#start': function(event, template) {
Meteor.call('startStack', template.data, function(error, result) {
if(error){
console.log(error);
} else {
console.log('response: ', result);
}
});
}
});
}
if (Meteor.isServer) {
spawn = Npm.require('child_process').spawn;
Meteor.methods({
startStack: function(branch) {
command = spawn('sh', ['-c', "ls && sleep 2 && ls -l && sleep 3 && ls -la"]);
Logs.update({ branch: branch['name'] }, { branch: branch['name'], text:''}, { upsert : true });
command.stdout.on('data', function (data) {
// TODO: concat to existing text
Logs.update({ branch: branch['name'] }, { branch: branch['name'], text: ''+data});
});
}
});
}