jeromq
jeromq copied to clipboard
Add timeout parameters to ZMsg.recv() and ZMQ.Socket.recv()
It seems there are 2 ways to block for an incoming message with a timeout, which is very common in client-side code.
One is to temporarily set the receive timeout property on the socket, then issue ZMQ.Socket.recv() or ZMsg.recv(), then set the timeout property back to whatever it was before, like so:
int originalTimeout = theRequestSocket.getReceiveTimeOut();
theRequestSocket.setReceiveTimeOut(500);
ZMsg.recvMsg();
theRequestSocket.setReceiveTimeOut( originalTimeout );
The other is to use the poller, which doesn't affect the recv timeout property of the socket, but is significantly more inconvenient:
ZMsg response = null;
ZMQ.Poller poller = new ZMQ.Poller(1);
poller.register( theRequestSocket, ZMQ.Poller.POLLIN );
int signalled = poller.poll( theTimeoutUnit.toMillis(theTimeout) );
if ( signalled == 1 ) {
response = ZMsg.recvMsg(theRequestSocket);
}
Both approaches are a little awkward. It seems like a timeout would in many cases, for clients anyway, need to be a per-request parameter on recv() calls.
Why not provide overloads for both the ZMQ.Socket.recv() and ZMsg.recv() methods that take a timeout parameter and do not have any side effects on the socket itself?
Life would be much better for clients if this could be achieved like so:
ZMsg response = ZMsg.recvMsg(500);
...or, even better:
ZMsg response = ZMsg.recvMsg( (long) 5, TimeUnit.SECONDS);
I like this idea a lot, and I don't see why it shouldn't be added to JeroMQ as a convenience.
One is to temporarily set the receive timeout property on the socket, then issue ZMQ.Socket.recv() or ZMsg.recv(), then set the timeout property back to whatever it was before, like so:
int originalTimeout = theRequestSocket.getReceiveTimeOut(); theRequestSocket.setReceiveTimeOut(500); ZMsg.recvMsg(); theRequestSocket.setReceiveTimeOut( originalTimeout );
I think this approach makes the most sense. Because sockets are not threadsafe, there is no possibility of a race condition if the application is being written responsibly (i.e. not receiving on a socket in multiple threads at the same time).
Life would be much better for clients if this could be achieved like so:
ZMsg response = ZMsg.recvMsg(500);...or, even better:
ZMsg response = ZMsg.recvMsg( (long) 5, TimeUnit.SECONDS);
I think we have to go with the second option anyway, since there is already a single integer arity of ZMQ$Socket.receive, that integer being the flags. I like option 2 better anyway :)