Add disconnect method to forked child processes
This disconnect method allows the child to exit gracefully. This also adds a disconnect event and connect property.
This commit is contained in:
parent
52bd0f93bb
commit
836344c90e
@ -24,6 +24,13 @@ of the signal, otherwise `null`.
|
|||||||
|
|
||||||
See `waitpid(2)`.
|
See `waitpid(2)`.
|
||||||
|
|
||||||
|
### Event: 'disconnect'
|
||||||
|
|
||||||
|
This event is emitted after using the `.disconnect()` method in the parent or
|
||||||
|
in the child. After disconnecting it is no longer possible to send messages.
|
||||||
|
An alternative way to check if you can send messages is to see if the
|
||||||
|
`child.connected` property is `true`.
|
||||||
|
|
||||||
### child.stdin
|
### child.stdin
|
||||||
|
|
||||||
A `Writable Stream` that represents the child process's `stdin`.
|
A `Writable Stream` that represents the child process's `stdin`.
|
||||||
@ -264,7 +271,12 @@ processes:
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
To close the IPC connection between parent and child use the
|
||||||
|
`child.disconnect()` method. This allows the child to exit gracefully since
|
||||||
|
there is no IPC channel keeping it alive. When calling this method the
|
||||||
|
`disconnect` event will be emitted in both parent and child, and the
|
||||||
|
`connected` flag will be set to `false`. Please note that you can also call
|
||||||
|
`process.disconnect()` in the child process.
|
||||||
|
|
||||||
### child.kill([signal])
|
### child.kill([signal])
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ function setupChannel(target, channel) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channel.buffering = false;
|
||||||
channel.onread = function(pool, offset, length, recvHandle) {
|
channel.onread = function(pool, offset, length, recvHandle) {
|
||||||
if (recvHandle && setSimultaneousAccepts) {
|
if (recvHandle && setSimultaneousAccepts) {
|
||||||
// Update simultaneous accepts on Windows
|
// Update simultaneous accepts on Windows
|
||||||
@ -117,10 +118,11 @@ function setupChannel(target, channel) {
|
|||||||
start = i + 1;
|
start = i + 1;
|
||||||
}
|
}
|
||||||
jsonBuffer = jsonBuffer.slice(start);
|
jsonBuffer = jsonBuffer.slice(start);
|
||||||
|
this.buffering = jsonBuffer.length !== 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
channel.close();
|
this.buffering = false;
|
||||||
target._channel = null;
|
target.disconnect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -129,7 +131,7 @@ function setupChannel(target, channel) {
|
|||||||
throw new TypeError('message cannot be undefined');
|
throw new TypeError('message cannot be undefined');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target._channel) throw new Error("channel closed");
|
if (!this.connected) throw new Error("channel closed");
|
||||||
|
|
||||||
// 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) {
|
||||||
@ -154,6 +156,34 @@ function setupChannel(target, channel) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
target.connected = true;
|
||||||
|
target.disconnect = function() {
|
||||||
|
if (!this.connected) return;
|
||||||
|
|
||||||
|
// do not allow messages to be written
|
||||||
|
this.connected = false;
|
||||||
|
this._channel = null;
|
||||||
|
|
||||||
|
var fired = false;
|
||||||
|
function finish() {
|
||||||
|
if (fired) return;
|
||||||
|
fired = true;
|
||||||
|
|
||||||
|
channel.close();
|
||||||
|
target.emit('disconnect');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a message is being read, then wait for it to complete.
|
||||||
|
if (channel.buffering) {
|
||||||
|
this.once('message', finish);
|
||||||
|
this.once('internalMessage', finish);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish();
|
||||||
|
};
|
||||||
|
|
||||||
channel.readStart();
|
channel.readStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,11 +231,8 @@ exports.fork = function(modulePath /*, args, options*/) {
|
|||||||
|
|
||||||
if (!options.thread) setupChannel(child, options.stdinStream);
|
if (!options.thread) setupChannel(child, options.stdinStream);
|
||||||
|
|
||||||
child.on('exit', function() {
|
// Disconnect when the child process exits.
|
||||||
if (child._channel) {
|
child.once('exit', child.disconnect.bind(child));
|
||||||
child._channel.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user