我们希望在需要RPC功能的项目中使用NodeJs DNode (https://github.com/substack/dnode)。它已经安装和测试过了,看起来很适合这个项目。
有一个小问题。远程函数可以是用户定义的,因此我们将无法控制逻辑。这意味着函数可能写得很糟糕,执行时间过长,甚至可能永远不会完成(无限循环)。
所以问题:是否有一种方法实现超时检查/事件/触发在产生的服务器连接/调用。
例:如果函数的执行时间超过5秒,则中止该函数,并向客户端返回异常信息。
注意:我们已经在客户端实现了超时逻辑,所以这不是问题。只是不想让虚假的僵尸进程无缘无故地阻塞服务器组件。
编辑: * ——添加代码示例 *
服务器(监听端口8000,callMe()函数调用doWork(),永不结束)
var dnode = require('dnode');
function doWork(cltId) {
console.log('Client:' + cltId);
setTimeout(function() { doWork(cltId); }, 5000);
}
var server = dnode({
callMe: function (cltId, cb) {
doWork(cltId);
}
});
server.listen(8000);
客户端(连接到端口8000和rpc callMe(),它从不返回)
var dnode = require('dnode');
var net = require('net');
var d = dnode();
d.on('remote', function (remote) {
var cltId = 'c-' + Math.random().toString(16).slice(2);
remote.callMe(cltId , function (s) {
console.log('Result=' + n);
d.end();
});
});
var conn = net.connect(8000);
conn.pipe(d).pipe(conn);
当客户端运行时,它将挂起,但它可以被杀死或超时设置以结束连接。这样客户就可以继续做其他事情了。
服务器仍然会愉快地把我们这段永不结束的代码拖走……
随着越来越多的客户端连接并调用躲闪代码,我们最终会有更多的虚假僵尸,直到最终我可以想象所有的服务器资源被消耗。
我想你对dnode做什么感到困惑。与dnode一起使用的函数只在定义它们时执行。它可能看起来好像回调被序列化并在连接的另一端执行,但事实并非如此。
例如,如果客户端这样做:
var d = dnode({
callMe: function () { while (true) }
});
d.pipe(stream).pipe(d);
和服务器调用callMe()
,客户端将挂在while (true)
上,而不是服务器。
您的客户端代码可以这样做:
d.on('remote', function (remote) {
var cltId = 'c-' + Math.random().toString(16).slice(2);
var t = setTimeout(function() {
t = null;
console.log("timed out!");
d.end();
}, 5e3);
remote.callMe(cltId , function (s) {
if(t === null) return; //too late...
clearTimeout(t);
console.log('Result=' + n);
d.end();
});
});
(未测试)