Support sending handles to other processes
Needs test.
This commit is contained in:
parent
d2ab314e08
commit
b413c77583
@ -190,8 +190,8 @@ leaner than `child_process.exec`. It has the same options.
|
|||||||
This is a special case of the `spawn()` functionality for spawning Node
|
This is a special case of the `spawn()` functionality for spawning Node
|
||||||
processes. In addition to having all the methods in a normal ChildProcess
|
processes. In addition to having all the methods in a normal ChildProcess
|
||||||
instance, the returned object has a communication channel built-in. The
|
instance, the returned object has a communication channel built-in. The
|
||||||
channel is written to with `child.send(message)` and messages are recieved
|
channel is written to with `child.send(message, [sendStream])` and messages
|
||||||
by a `'message'` event on the child.
|
are recieved by a `'message'` event on the child.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
@ -224,6 +224,10 @@ These child Nodes are still whole new instances of V8. Assume at least 30ms
|
|||||||
startup and 10mb memory for each new Node. That is, you cannot create many
|
startup and 10mb memory for each new Node. That is, you cannot create many
|
||||||
thousands of them.
|
thousands of them.
|
||||||
|
|
||||||
|
The `sendStream` option to `child.send()` is for sending a `net.Socket`
|
||||||
|
or `net.Server` object to another process. Child will receive the handle as
|
||||||
|
as second argument to the `message` event.
|
||||||
|
|
||||||
|
|
||||||
### child.kill(signal='SIGTERM')
|
### child.kill(signal='SIGTERM')
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ function setupChannel(target, channel) {
|
|||||||
|
|
||||||
var jsonBuffer = '';
|
var jsonBuffer = '';
|
||||||
|
|
||||||
channel.onread = function(pool, offset, length) {
|
channel.onread = function(pool, offset, length, recvStream) {
|
||||||
if (pool) {
|
if (pool) {
|
||||||
for (var i = 0; i < length; i++) {
|
for (var i = 0; i < length; i++) {
|
||||||
if (pool[offset + i] === LF) {
|
if (pool[offset + i] === LF) {
|
||||||
@ -82,7 +82,7 @@ function setupChannel(target, channel) {
|
|||||||
jsonBuffer = pool.toString('ascii', i, length);
|
jsonBuffer = pool.toString('ascii', i, length);
|
||||||
offset = i + 1;
|
offset = i + 1;
|
||||||
|
|
||||||
target.emit('message', message);
|
target.emit('message', message, recvStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -91,11 +91,14 @@ function setupChannel(target, channel) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
target.send = function(message, fd) {
|
target.send = function(message, sendStream) {
|
||||||
if (fd) throw new Error("not yet implemented");
|
|
||||||
|
|
||||||
if (!target._channel) throw new Error("channel closed");
|
if (!target._channel) throw new Error("channel closed");
|
||||||
|
|
||||||
|
// Open up net.Socket instances
|
||||||
|
if (sendStream instanceof require('net').Socket) {
|
||||||
|
sendStream = sendStream._handle;
|
||||||
|
}
|
||||||
|
|
||||||
// For overflow protection don't write if channel queue is too deep.
|
// For overflow protection don't write if channel queue is too deep.
|
||||||
if (channel.writeQueueSize > 1024 * 1024) {
|
if (channel.writeQueueSize > 1024 * 1024) {
|
||||||
return false;
|
return false;
|
||||||
@ -103,7 +106,7 @@ function setupChannel(target, channel) {
|
|||||||
|
|
||||||
var buffer = Buffer(JSON.stringify(message) + '\n');
|
var buffer = Buffer(JSON.stringify(message) + '\n');
|
||||||
|
|
||||||
var writeReq = channel.write(buffer);
|
var writeReq = channel.write(buffer, 0, buffer.length, sendStream);
|
||||||
|
|
||||||
if (!writeReq) {
|
if (!writeReq) {
|
||||||
throw new Error(errno + " cannot write to IPC channel.");
|
throw new Error(errno + " cannot write to IPC channel.");
|
||||||
|
@ -292,8 +292,7 @@ Handle<Value> StreamWrap::Write(const Arguments& args) {
|
|||||||
} else {
|
} else {
|
||||||
uv_stream_t* send_stream = NULL;
|
uv_stream_t* send_stream = NULL;
|
||||||
|
|
||||||
if (args.Length() > 3) {
|
if (args[3]->IsObject()) {
|
||||||
assert(args[3]->IsObject());
|
|
||||||
Local<Object> send_stream_obj = args[3]->ToObject();
|
Local<Object> send_stream_obj = args[3]->ToObject();
|
||||||
assert(send_stream_obj->InternalFieldCount() > 0);
|
assert(send_stream_obj->InternalFieldCount() > 0);
|
||||||
StreamWrap* send_stream_wrap = static_cast<StreamWrap*>(
|
StreamWrap* send_stream_wrap = static_cast<StreamWrap*>(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user