Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js sending an object with function definitions to worker thread

So I am working on a project in Node.js and I want to open up some extra threads to handle the processing load more efficiently. But I am using classes with function definitions with them and when I try to send those objects to the worker thread, the functions defined in the object disappear and I am only left with the other fields in the object. Is there a way to send the worker an object and preserve the functions so they can be called within the worker?

var cluster = require('cluster');

if(cluster.isMaster){
    Monster = function(species){
        this.attack = function(){
            console.log('CHOMP');
        };
        this.name = species;
    };
    var vamp = new Monster('vampire'),
    worker   = cluster.fork();
    worker.send({'monster' : vamp});
    }
else{
    process.on('message', function(msg) {
        console.log(msg.monster); //this logs "{ name: 'vampire' }"  
        msg.monster.attack(); //TypeError: Object #<Object> has no method 'attack'
    });
}
like image 483
Charlie Lipford Avatar asked Sep 06 '12 15:09

Charlie Lipford


2 Answers

No, there is no way to pass functions between threads. You can pass only JS plain objects (data only) and handle it with functions defined in current thread (like create new object with received data).

like image 173
Vadim Baryshev Avatar answered Nov 14 '22 08:11

Vadim Baryshev


Charlie, I realize you asked this question a year ago, but I was wanting to do something very similar and I came across your question which you didn't mark an answer to yet. I thought I would take a "stab" at it and show you what I have done with your code. This different way of organizing code is for me a very acceptable workaround in my node.js work. I am pretty sure this gives you a way to accomplish what you want, even though you can't do it in the manner you wanted.

Declare your "class" outside the cluster code, like this:

var cluster = require('cluster');

var Monster = function(species){
    this.attack = function(){
        console.log('CHOMP!');
    };
    this.die = function() {
        console.log("Oh, what did I eat?  I don't feel so good....\r\n");
        process.exit(0);
    };
    this.scare = function() {
        console.log("BOO! I am a " + this.name + "!");
    };
    this.name = species;
};

if(cluster.isMaster){
    worker = cluster.fork();
    worker.send({'species' : 'Vampire'});
}
else{
    process.on('message', function(msg) {
        if(typeof msg.species !== "undefined") {
            myMonster = new Monster(msg.species);
            myMonster.scare();
            myMonster.attack();
            myMonster.die();
        }
    });
}

Give that a whirl and see if this is an answer you can accept!

like image 2
Geek Stocks Avatar answered Nov 14 '22 06:11

Geek Stocks