[zeromq-dev] Functionality of connect/disconnect bind/unbind
Siam Rafiee
siamraf at gmail.com
Fri May 24 11:18:38 CEST 2013
The pending messages are destroyed because there's nowhere else for them to
go.
A socket maintains a queue per peer (each connect/bind destination being a
peer). When you do a send() on a PUSH socket, it will put the message on
the outbound queue for one of its peers (simple round robin). When you
disconnect/unbind the socket from a peer, that peer's queue is destroyed
along with all the pending messages in it. Even if ZeroMQ were to hold onto
these pending messages in a separate queue within the socket - there's
still no guarantee that you won't lose messages. Messages can be stuck in
various TCP buffers across the network stack when you fail over, out of
reach of ZeroMQ.
If you need to guarantee no messages are lost, what you really need are
application-level acks for your messages, and/or your own buffering
mechanism to resend any lost messages when you fail over.
Siam
On 23 May 2013 16:10, Trevor Bernard <trevor.bernard at gmail.com> wrote:
> Thanks for follow-up Siam.
>
> I thought I could get away with using POLL_OUT but alas, no luck.
>
> Is there any reason why the pending messages are destroyed?
>
>
>
> On Thu, May 23, 2013 at 7:58 AM, Siam Rafiee <siamraf at gmail.com> wrote:
>
>> This behaviour actually affects my system too (looks like we're modeling
>> failovers in the same way), so I followed this up on the #zeromq irc
>> channel, where guido_g helped clarify why this is happening.
>>
>> [For those more familiar with Java-style syntax, I've reproduced the code
>> here http://pastebin.com/BD6kL20g ].
>>
>> A zmq socket maintains a separate queue for each connected peer. When you
>> disconnect the PUSH socket from localhost:12345, that queue is destroyed
>> (along with any messages pending on it). When the PUSH socket is then
>> connected to the new endpoint, a new (empty) queue is created. Thus, only
>> "msg9" (which is sent after this queue is created) will be delivered when
>> the PULL side eventually binds at the new endpoint.
>>
>> Cheers,
>>
>> Siam
>>
>>
>> On 22 May 2013 23:58, Apostolis Xekoukoulotakis <xekoukou at gmail.com>wrote:
>>
>>> Sorry, wrong answer.
>>>
>>>
>>> 2013/5/23 Apostolis Xekoukoulotakis <xekoukou at gmail.com>
>>>
>>>> You are probably disconnecting push before it is able to send the msgs.
>>>>
>>>>
>>>> 2013/5/23 Trevor Bernard <trevor.bernard at gmail.com>
>>>>
>>>>> I'm using libzmq 3.2.3
>>>>>
>>>>>
>>>>>
>>>>> On Wed, May 22, 2013 at 12:05 PM, Trevor Bernard <
>>>>> trevor.bernard at gmail.com> wrote:
>>>>>
>>>>>> What should the functionality be for the following scenario?
>>>>>>
>>>>>> ;; Conceptually, assume push and pull sockets are different processes
>>>>>> (def ctx (zcontext 1))
>>>>>> (def ctx2 (zcontext 2))
>>>>>>
>>>>>> (def push (-> (socket ctx :push)
>>>>>> (connect "tcp://localhost:12345")))
>>>>>> (send push (.getBytes "msg1")) ;; true
>>>>>> (send push (.getBytes "msg2")) ;; true
>>>>>>
>>>>>>
>>>>>> (def pull (-> (socket ctx2 :pull)
>>>>>> (bind "tcp://*:12345")))
>>>>>>
>>>>>> ;; receive queued messages as expected
>>>>>> (String. (recv pull)) "msg1"
>>>>>> (String. (recv pull)) "msg2"
>>>>>> (close pull) ;; simulate loss of connection
>>>>>>
>>>>>> (send push (.getBytes "msg3"))
>>>>>> (send push (.getBytes "msg4"))
>>>>>> (send push (.getBytes "msg5"))
>>>>>>
>>>>>> (def pull2 (-> (socket ctx2 :pull)
>>>>>> (bind "tcp://*:12345")))
>>>>>>
>>>>>> ;; Again, received queued messages
>>>>>> (String. (recv pull2)) ;; "msg3"
>>>>>> (String. (recv pull2)) ;; "msg4"
>>>>>> (String. (recv pull2)) ;; "msg5"
>>>>>> (close pull2)
>>>>>>
>>>>>> (send push (.getBytes "msg6")) ;; true
>>>>>> (send push (.getBytes "msg7")) ;; true
>>>>>> (send push (.getBytes "msg8")) ;; true
>>>>>>
>>>>>> ;; Simulate failover to a new endpoint
>>>>>> (disconnect push "tcp://localhost:12345")
>>>>>> (connect push "tcp://localhost:1337")
>>>>>>
>>>>>> (send push (.getBytes "msg9")) ;; true
>>>>>> (def pull3 (-> (socket ctx2 :pull)
>>>>>> (bind "tcp://*:1337")))
>>>>>>
>>>>>> ;; Expected to receive msg6-9
>>>>>> (String. (recv pull3)) ;; "msg9"
>>>>>>
>>>>>> I expected the messages to be queued up and to receive msg6..9 but
>>>>>> only received msg9. Are messages 6-8 lost?
>>>>>>
>>>>>> -Trev
>>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> zeromq-dev mailing list
>>>>> zeromq-dev at lists.zeromq.org
>>>>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>>
>>>>
>>>> Sincerely yours,
>>>>
>>>> Apostolis Xekoukoulotakis
>>>>
>>>>
>>>
>>>
>>> --
>>>
>>>
>>> Sincerely yours,
>>>
>>> Apostolis Xekoukoulotakis
>>>
>>>
>>> _______________________________________________
>>> 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20130524/114357a9/attachment.htm>
More information about the zeromq-dev
mailing list