简体   繁体   English

分叉子进程并注入依赖

[英]Fork a child process and inject dependency

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: 然后在我的worker模块中:

module.exports = function (dependency) {
  // Outputs { name: "Bob" }
  console.log(dependency)
}

How can I turn this example into a child process being forked? 如何将此示例转换为分叉的子进程?

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). 使用.fork()时,您正在启动一个完全独立的进程,因此您无法在父进程和子进程之间传递引用(并且仅限于创建进程后的消息传递)。

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.
    }
});

a.js 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 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 b.js

var a = require ("./a");
a.init ({ name: "asd" });
a.print ("hi, ");
setTimeout (function (){
    a.uninit ();
}, 1000);

Prints: hi, asd 印刷品:嗨,asd

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): 并在子进程模块(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();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM