Ale*_*lls 17 javascript zeromq node.js
在我编写的一些Node.js脚本中,我注意到即使最后一行是同步调用,有时它也会在Node.js退出之前完成.
我从未见过一个console.log语句在退出之前无法运行/完成,但我看到其他一些语句在退出之前未能完成,我相信它们都是同步的.我可以理解为什么在这种情况下异步函数的回调当然无法触发.
有问题的代码是ZeroMQ .send()调用,如下所示:
var zmq = require('zmq');
var pub = zmq.socket('pub');
pub.bindSync('tcp://127.0.0.1:5555');
setInterval(function(){
pub.send('polyglot');
},500);
Run Code Online (Sandbox Code Playgroud)
上面的代码按预期工作...但如果我删除setInterval()并只是这样调用它:
var zmq = require('zmq');
var pub = zmq.socket('pub');
pub.bindSync('tcp://127.0.0.1:5555');
pub.send('polyglot'); //this message does not get delivered before exit
process.exit(0);
Run Code Online (Sandbox Code Playgroud)
...然后消息将无法传递 - 程序将在pub.send()呼叫完成之前退出.
在Node.js中退出之前确保语句完成的最佳方法是什么?关机挂钩可以在这里工作,但我担心这只会掩盖问题,因为你不能把所有你需要的东西确保在关机钩子中运行.
这个问题也可以通过这种方式证明:
if (typeof messageHandler[nameOfHandlerFunction] == 'function') {
reply.send('Success');
messageHandler[nameOfHandlerFunction](null, args);
} else {
reply.send('Failure'); //***this call might not complete before the error is thrown below.***
throw new Error('SmartConnect error: no handler for ZMQ message sent from Redis CSV uploader.');
}
Run Code Online (Sandbox Code Playgroud)
我认为这是一个合法/严重的问题,因为很多程序只需要发布消息然后死掉,但我们怎样才能有效地确保所有消息都被发送(虽然不一定收到)?
编辑:解决此问题的一种(潜在)方法是:
socket.send('xyz');
socket.close(); // supposedly this will block until the above message is sent
process.exit(0);
Run Code Online (Sandbox Code Playgroud)
跳水进入zeromq.node,你可以看到Socket.send刚才推你的数据_outgoing:
this._outgoing.push([msg, flags]);
Run Code Online (Sandbox Code Playgroud)
...然后调用_flushiff zmq.ZMQ_SNDMORE未设置:
this._flush();
Run Code Online (Sandbox Code Playgroud)
看起来_flush实际上是在做socket编写.如果_flush()失败,则会发出错误.
编辑:
我猜pub.unbind()在退出之前打电话,会强制_flush()被叫:
pub.unbind('tcp://127.0.0.1:5555', function(err) {
if (err) console.log(err);
process.exit(0); // Probably not even needed
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
661 次 |
| 最近记录: |