简体   繁体   中英

DNode server method timeout

We are looking to use NodeJs DNode ( https://github.com/substack/dnode ) in a project where we need RPC functionality. It has been setup and tested and seems a good fit for the project.

One small niggle though. The remote functions can be user-defined and thus we will have no control over the logic. This means the function could be badly written and take an excessive amount of time to execute or perhaps even never complete (endless loop).

So question : Is there a way of implementing a timeout check/event/trigger on the spawned server connections/calls.
eg If the function exceeds 5 seconds execution time, abort it and return exception information to the client.

Note: We have implemented timeout logic on the client, so this is not a problem. Just do not want spurious zombie processes clogging up the server component for no reason.

EDIT: * -- Add code examples -- *
Server (Listens on port 8000, callMe() function calls doWork() , never ending.)

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);

Client (connect to port 8000 and rpc callMe() , which never returns)

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);

When the client runs, it will hang but it can be either killed or a timeout set which ends the connection. So the client can get on with doing something else.

BUT

The server will still be merrily punting away with our never ending piece of code...
And as more clients connect and call the dodge code we end up with additional spurious zombies until eventually I would imagine all server resources are consumed.

I think you are confused about what dnode does. Functions that you use with dnode only ever execute on the side they were defined. It might look as though callbacks are getting serialized and executed on the other side of the connection, but they are not.

For instance if a client does:

var d = dnode({
  callMe: function () { while (true) }
});
d.pipe(stream).pipe(d);

and the server calls callMe() , the client will hang on the while (true) , not the server.

Your client code could do:

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();
    });
});

(Untested!)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM