问题
I currently have an operation in a module that is blocking, so I'm looking at making this into a child process that I fork instead.
If I want to do that, then I of course need to modify the architecture of my module. The module requires that a dependency is injected by calling the module as a function, passing in the dependency, like so:
var dependency = { name: "Bob" }
require('worker')(dependency)
Then in my worker
module:
module.exports = function (dependency) {
// Outputs { name: "Bob" }
console.log(dependency)
}
How can I turn this example into a child process being forked?
回答1:
When using .fork() you are spinning up a completely separate process, so you are not able to pass around references between the parent and child processes (and are limited to messaging after the process has been created).
An approach not requiring messaging is to pass arguments (in an array) when you fork the process. Although I believe you'll have to stick with simple string/number values (but it looks like this might be enough for you from the code). Eg.:
At top level:
var name = 'bob'
var args = [name];
var childProcess = require('child_process').fork(__dirname + '/worker', args);
In the worker process:
var name = process.argv[2]; //AFIAK elements 0 and 1 are already populated with env info
Update
If you really want to go the messaging route (which I'd hesitate to recommend if you already need to send messages), then you could differentiate between the types of messages something like this (there may be more elegant ways):
At top level:
var childProcess = require('child_process').fork(__dirname + '/worker');
childProcess.send({msgtype:'dependencies', content:dependencies});
//Then to send 'normal' message:
childProcess.send({msgtype:'myothermessagetype', content:'some content'}
In worker process:
process.on('message', function(msg){
if(msg.mtype == 'dependencies') {
var dependencies = msg.content;
//Do something with dependencies
} else if(msg.mtype == 'myothermessagetype') {
var normalmessage = msg.content;
//Do something in response to normal message.
}
});
回答2:
a.js
var fork = require ("child_process").fork;
var child;
var init = false;
var m = module.exports = {};
m.init = function (o){
if (init) return;
init = true;
child = fork (__dirname + "/child");
child.send ({ init: o });
};
m.print = function (o){
if (!init) return;
child.send ({ msg: o });
};
m.uninit = function (){
if (!init) return;
child.on ("exit", function (){
init = false;
});
child.kill ();
};
child.js
var dependency;
var print = function (o){
console.log (o + dependency.name);
};
process.on ("message", function (o){
if (o.init){
dependency = o.init;
}else{
print (o.msg);
}
});
b.js
var a = require ("./a");
a.init ({ name: "asd" });
a.print ("hi, ");
setTimeout (function (){
a.uninit ();
}, 1000);
Prints: hi, asd
回答3:
In the main module:
var dependency = {message: 'hello there'};
var args = [JSON.stringify(dependency)];
var child = require('child_process').fork('worker', args);
child.send('sayhello');
child.send('exit');
And in the child process module (worker.js):
var dependency = JSON.parse(process.argv[2]);
process.on('message', function(m){
if(m == 'sayhello') console.log(dependency.message);
else if(m == 'exit') process.exit();
});
来源:https://stackoverflow.com/questions/15368436/fork-a-child-process-and-inject-dependency