Question

I've build a simple model in c++ which one I would like meteor to interact with. Currently the model is run as a command line and everything is working pretty well but calling the command line is done asynchronously. The model is very fast and therefore I do not need the result to come in a callback, moreover involving callbacks in this process makes the meteor's DB access more complicated and this is something I would like to avoid.

So, we just come in the regular question : how to make something async sync in javascript…

I know that this has been discussed using node, this topic is answered here already: node.js execute system command synchronously

This say, how to actually do/setup this within meteor ?

We should install the packages using npm but as Meteor changed it's distribution system what is then the way to let it handle the npm packages by itself ? Take a look here to see what I'm talking about, I have not been able to find any relevant information about this package.js

In order to avoid installing external packages, I thought about using Fibers, which is internally used by meteor, but still: Do someone have an example on how to encapsulate an async call with it ? Last but not least, the Fibers developers almost advise us not to directly code with Fiber but to use some other sub tool using it already… why not but I'm back to the question on how to include npm packages

my code looks like this (a little bit simplified):

function callToEngine(argument, callback)
            {
               var result = null;
               var modelPath = "/some/where"

               var require = Npm.require;
               var spawn = require('child_process').spawn;
               var model = spawn(modelPath, []);
               var answerBuffer = "";

               engine.stdin.write(argument);
               engine.stdin.end(); //flush

                engine.stdout.on('data', function(data)
                {
                    answerBuffer+=data;
                });

                engine.stderr.on('data', function(data)
                {
                    console.log('stderr: ' + data);
                });

                engine.on('close', function(code)
                {
                    result = JSON.parse(answerBuffer);
                    console.log('child process exited with code ' + code);
                    callback(result);
                });
            }

I would like to have something like:

var result = callToEngine(argument);
Was it helpful?

Solution

You could use a future:

function callToEngine(argument) {
    var Future = Npm.require('fibers/future');

    var fut = new Future();


    ///do stuff

    engine.on('close', function(code)
            {
                result = JSON.parse(answerBuffer);
                console.log('child process exited with code ' + code);
                fut.return(result);
            });

    return fut.wait();
}

Then simply use:

var result = callToEngine(argument);

The future will ensure that return will only return something when fut.return is run

More info on other designs at the Meteor Async Guide : https://gist.github.com/possibilities/3443021

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top