[zeromq-dev] Closed dealer socket may cause context termination to hang

Pieter Hintjens ph at imatix.com
Thu Nov 6 10:59:30 CET 2014


Good idea. Let me try that... OK, I've added a warning to the
zmq_ctx_term man page.

The default behavior is so unhelpful that we might consider changing
it. E.g. change the default linger on sockets from infinity to e.g. 5
seconds.

On Thu, Nov 6, 2014 at 9:02 AM, Michi Henning <michi at triodia.com> wrote:
> A doc patch for this would be really nice. I've been bitten by this as well.
>
> Michi.
>
>
> On 6 Nov 2014, at 17:56 , Pieter Hintjens <ph at imatix.com> wrote:
>
>> You have to set linger=0 on the socket before closing it.
>>
>> There are two old design mistakes in libzmq which cause this. One is
>> the default linger of infinity. I'd have changed that ages ago except
>> would break compatibility. The other is libzmq's shutdown logic, which
>> can't handle even the simple case you showed. It's worse... try just
>> creating the socket and connecting, then terminating, and it blocks.
>>
>> The good news is you can trivially fix this. Set linger=0 on all
>> sockets before destroying them, and destroy all sockets before
>> terminating. Or use a binding like CZMQ which does this for you.
>>
>> There is IME no value in "waiting for messages to be sent" in normal
>> operation. That happens only in apps which fire up, send a message,
>> then exit. Rare. Normal ZeroMQ apps run forever and message loss at
>> the end of a connection is always dealt with at a higher level.
>>
>> -Pieter
>>
>> On Thu, Nov 6, 2014 at 1:13 AM, André Caron <andre.l.caron at gmail.com> wrote:
>>> Hi there,
>>>
>>> I've been bit by this nasty little bugger and I thought I'd share.
>>>
>>> In this little snippet, terminating the context hangs unless the connection
>>> was established, even though we're closing the socket properly before
>>> terminating the context.
>>>
>>>    import zmq
>>>    c = zmq.Context()
>>>    s = c.socket(zmq.DEALER)
>>>    s.connect('tcp://127.0.0.1:66')
>>>    s.send_multipart(['foo', 'bar', 'meh'])
>>>    s.close()
>>>    c.term()  # hangs (until someone starts listening on port 666).
>>>
>>> It happens that if you put a linger on the socket when closing it, the
>>> program shuts down nicely.
>>>
>>> Took me a while to figure out why, but it seems this is a symptom of that
>>> little subtlety between bind and connect in ZeroMQ.  I remember reading
>>> about this somewhere in the guide, but I probably thought I'd come back to
>>> this concept and never did.  So apparently, the dealer socket immediately
>>> creates a queue for messages when you call "zmq_connect()", even if the TCP
>>> connection is never established and somehow this queue that never gets
>>> flushed if you don't establish a connection.
>>>
>>> I'm really surprised by this behavior.  I would think that closing the
>>> dealer socket would stop the reconnection attempts, and then the socket
>>> would drop the queue and allow the context to terminate (as when I set the
>>> linger on the socket).
>>>
>>> I know the queue creation on "zmq_connect()" is by design, but is the
>>> attempt to connect to the peer after the dealer socket is closed desired as
>>> well?
>>>
>>> If it is, I'd like to know if there is a place to document these kinds of
>>> gotchas.  If so, I'd probably send in a documentation patch for this
>>> particular one.
>>>
>>> Cheers,
>>>
>>> André
>>>
>>> _______________________________________________
>>> zeromq-dev mailing list
>>> zeromq-dev at lists.zeromq.org
>>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>>>
>> _______________________________________________
>> zeromq-dev mailing list
>> zeromq-dev at lists.zeromq.org
>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>>
>
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev



More information about the zeromq-dev mailing list