// RoundRobinHandle
this.handle.onconnection = (err, handle) => this.distribute(err, handle);
// distribute 对工作进程进行分发
RoundRobinHandle.prototype.distribute = function(err, handle) {
this.handles.push(handle); // 存入TCP服务的句柄
const worker = this.free.shift(); // 取出第一个工作进程
if (worker)
this.handoff(worker); // 切换到工作进程
};
RoundRobinHandle.prototype.handoff = function(worker) {
const handle = this.handles.shift(); // 获取TCP服务句柄
if (handle === undefined) {
this.free.push(worker); // 将该工作进程重新放入队列中
return;
}
const message = { act: 'newconn', key: this.key };
// 向工作进程发送一个类型为 newconn 的消息以及TCP服务的句柄
sendHelper(worker.process, message, handle, (reply) => {
if (reply.accepted)
handle.close();
else
this.distribute(0, handle); // 工作进程不能正常运行,启动下一个
this.handoff(worker);
});
};
在子进程中也有对内部消息进行监听,在cluster/child.js中,有个cluster._setupWorker方法,该方法会对内部消息监听,该方法的在lib/internal/bootstrap/node.js中调用,这个文件是每次启动node命令后,由C++模块调用的。
链接
function startup() {
// ...
startExecution();
}
function startExecution() {
// ...
prepareUserCodeExecution();
}
function prepareUserCodeExecution() {
if (process.argv[1] && process.env.NODE_UNIQUE_ID) {
const cluster = NativeModule.require('cluster');
cluster._setupWorker();
delete process.env.NODE_UNIQUE_ID;
}
}
startup()
下面看看_setupWorker方法做了什么。
cluster._setupWorker = function() {
// ...
process.on('internalMessage', internal(worker, onmessage));
function onmessage(message, handle) {
// 如果act为 newconn 调用onconnection方法
if (message.act === 'newconn')
onconnection(message, handle);
else if (message.act === 'disconnect')
_disconnect.call(worker, true);
}
};
function onconnection(message, handle) {
const key = message.key;
const server = handles.get(key);
const accepted = server !== undefined;
send({ ack: message.seq, accepted });
if (accepted)
server.onconnection(0, handle); // 调用net中的onconnection方法
}
最后子进程获取到客户端句柄后,调用net模块的onconnection,对Socket进行实例化,后面就与其他http请求的逻辑一致了,不再细讲。
至此,cluster模块的逻辑就走通了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持黑区网络。
