javascript - NodeJS Event Emitter Blocking Issue -
i have node application handling zeromq events coming application utilizing node-zmq bindings found here: https://github.com/justintulloss/zeromq.node
the issue running 1 of operations event takes long time process , appears blocking other event being processed during time. although application not clustered, doing afford few more threads , doesn't solve issue. wondering if there way of allowing these async calls not block other incoming requests while process, , how might go implementing them.
here highly condensed/contrived code example of doing currently:
var zmq = require('zmq'); var zmqresponder = zmq.socket('rep'); var client = require('node-rest-client').client; var client = new client(); zmqresponder.on('message', function (msg, data) { var parsed = json.parse(msg); logging.info('zmq request received: ' + parsed.event); switch (parsed.event) { case 'create': //typically short running process, not issue case 'update': //long running process issue serverrequest().then(function(response){ zmqresponder.send(json.stringify(response)); }); } }); function serverrequest(){ var deferred = q.defer(); client.get(function (data, response) { if (response.statuscode !== 200) { deferred.reject(data.data); } else { deferred.resolve(data.data); } }); return deferred.promise; }
edit** here's gist of code: https://gist.github.com/battlecow/cd0c2233e9f197ec0049
i think, through comment thread, i've identified issue. req/rep
has strict synchronous message order guarantee... must receive-send-receive-send-etc. req
must start send , rep
must start receive. so, you're processing 1 message @ time because socket types you've chosen enforce that.
if using different, non-event-driven language, you'd error telling you'd done wrong when tried send or receive twice in row, node lets , queues subsequent messages until it's turn in message order.
you want change req/rep
dealer/router
, it'll work way expect. you'll have change logic router
socket send appropriately, else should work same.
rough example code, using relevant portions of posted gist:
var zmqresponder = zmq.socket('router'); zmqresponder.on('message', function (msg, data) { var peer_id = msg[0]; var parsed = json.parse(msg[1]); switch (parsed.event) { case 'create': // build parsedresponse, then... zmqresponder.send([peer_id, json.stringify(parsedresponse)]); break; } }); zmqresponder.bind('tcp://*:5668', function (err) { if (err) { logging.error(err); } else { logging.info("zmq awaiting orders on port 5668"); } });
... need grab peer_id
(or whatever want call it, in zmq nomenclature it's socket id of socket you're sending from, think of "address" of sorts) first frame of message receive, , use send first frame of message send back.
by way, noticed in gist both connect()
-ing , bind()
-ing on same socket (zmq.js lines 52 & 143, respectively). don't that. inferring other clues, want bind()
on side of process.
Comments
Post a Comment