txZMQ icon indicating copy to clipboard operation
txZMQ copied to clipboard

Timeout handling in REP-REQ

Open sveinse opened this issue 6 years ago • 1 comments

I'm not quite sure this is a bug or if its an intended feature, and I'd like to elaborate on this problem that I've spent some time figuring out:

I'm using REP-REQ in a context where the REP server is unstable. The txzmq implements a timeout on the ZmqREQConnection.sendMsg() method. This timeout works perfectly in itself, but after some digging it seems the timeout feature is not a part of zmg. The problem with this is that the message is still left in zmq REQ queue, even after the caller has already gotten its Errback() called for the this message. If the server becomes available at some later time, the reply will be send back to the REQ client, but it goes nowhere in the txzmq stack.

The second problem is that sending a message to the server is the only way of knowing if the server connection is alive, so one needs to keep sending messages (that will time out) regularly to check if the link is up. When it is up again, the server will be flooded with a stream of these "alive" messages.

My resolution to the issue is to use a variant of the lazy pirate pattern: When sending a message with sendMsg() I install an Errback callback that closes the link, which will flush the connection.

    if not socket:
        socket = ZmqREQConnection(zmq, req_endpoint)

    try:
        d = socket.sendMsg(message, timeout=2)

        def onTimeout(fail):
            socket.shutdown()
            socket = None
            return fail

        d.addErrback(onTimeout)
        return d

    except zmq.error.Again:
        print("Handle me...")

Since this is more an effect of the zmq's REP-REQ implementation than txzmq, I'm not sure this is a bug in txzmq, but I dislike that a message receives a timeout, while still being scheduled for transmission. Perhaps the above logic is required? Perhaps there is some way to cancel the message when it times out?

sveinse avatar Nov 18 '18 00:11 sveinse

good question, I don't think ZMQ has a feature to "un-send" a message, so I don't think we could do something at the library level

smira avatar Mar 05 '19 18:03 smira