2013-03-12 28 views
8

Aktualnie mam operację w module, który jest blokowany, więc szukam tego w procesie potomnym, który zamiast tego rozwidla.Rozwidlenie procesu potomnego i wstrzyknięcia zależnego

Jeśli chcę to zrobić, to oczywiście muszę zmodyfikować architekturę mojego modułu. Moduł wymaga, że ​​zależność jest wstrzykiwany przez wywołanie modułu jako funkcję, przekazując w zależności, jak w przykładzie:

var dependency = { name: "Bob" } 
require('worker')(dependency) 

potem w moim module worker:

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

Jak mogę włączyć tego przykładu do rozwidlenia procesu potomnego?

+0

rozwidlić dziecko, a następnie wysłać zależność od rodzica za pomocą child.send (wiadomość).Przekazany obiekt nie może być cykliczny. http://nodejs.org/api/all.html#all_child_process_fork_modulepath_args_options –

+0

@GabrielLlamas muszę użyć 'child.send (komunikat)' później faktycznie wysyłać dane do pracownika (a nie zależności). Nie rozumiem, w jaki sposób mój pracownik może rozróżnić, jaki rodzaj wiadomości jest wysyłany i jak sobie z nimi radzić. –

+0

cóż, robiłem kompletny przykład, gdy przyjąłeś inną odpowiedź, spójrz na to! –

Odpowiedz

19

Podczas korzystania z pliku .fork() przetwarza się całkowicie oddzielny proces, więc nie można przekazywać referencji między procesami nadrzędnymi i podrzędnymi (i są ograniczone do komunikatów po utworzeniu procesu).

Podejście niewymagające przesyłania komunikatów to przekazywanie argumentów (w tablicy) po rozwidleniu procesu. Chociaż uważam, że będziesz musiał trzymać się prostych wartości łańcuchów/liczb (ale wygląda na to, że może ci to wystarczyć z kodu). Np .:

Na górnym poziomie:

var name = 'bob' 
var args = [name]; 
var childProcess = require('child_process').fork(__dirname + '/worker', args); 

W procesie roboczym:

var name = process.argv[2]; //AFIAK elements 0 and 1 are already populated with env info 

aktualizacji

Jeśli naprawdę chcesz, aby przejść trasę wiadomości (co ja” d wahaj się polecić, jeśli już musisz wysyłać wiadomości), wtedy możesz rozróżnić rodzaje wiadomości w podobny sposób (mogą być bardziej eleganckie sposoby):

na najwyższym poziomie:

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'} 

W procesie roboczym:

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

Dziękuję za odpowiedź informacyjną. Niestety wymagam, aby obiekt został zaliczony ... choć przypuszczam, że mógłbym go skorygować. –

+0

Tak, osobiście, że będę stringify lub, jeśli to nie jest zbyt skomplikowane, włóż go tymczasowo do jego składników. Nie lubię komplikować logiki przesyłania komunikatów zarówno z instalacją, jak iz normalnymi "uruchomieniami". – UpTheCreek

+0

nie robiąc „węzeł a/b/c/app.js” –

0

W głównym 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'); 

A w module procesu potomnego (pracownika. 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(); 
}); 
0

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

Wydruki Cześć, USA