On Sat, 2017-09-02 at 12:02 -0400, Bill Torpey wrote: > Thanks again, Luca! > > For now, I’m going to go with disabling reconnect on the “data” > sockets — that seems to be the best solution for my use case > (connecting to endpoints that were returned by the peer binding to an > unspecified (“wildcard”) port — e.g., "tcp://<interface>:*" in ZMQ). > > This assumes that ZMQ will completely forget about the endpoint > if/when it is disconnected, if it is set not to reconnect. Otherwise > I might run afoul of ZMQ’s silently ignoring connections to endpoints > that it already knows about: https://github.com/zeromq/libzmq/issues > /788 <https://github.com/zeromq/libzmq/issues/788> (e.g., in the case > where another process later happens to be assigned the same ephemeral > port). > > I’ve done a quick scan of the libzmq code (v4.2.2) and it doesn’t > appear that the endpoint is removed in the case of a (terminal) > disconnect. If you can confirm/deny this behavior, that would be > helpful. Failing that, I guess I’ll need to test this in the > debugger — any hints on how best to do this would also be much > appreciated. > > Regards, > > Bill
Yes it doesn't look like it removes the endpoint - I guess it's a corner case that's missed. I'll open an issue. BTW all these things are very quick and easy to try with Python on Linux. Just install pyzmq, open a python3 terminal and: import zmq ctx = zmq.Context.instance() rep = ctx.socket(zmq.REP) rep.bind("tcp://127.0.0.1:12345") req = ctx.socket(zmq.REQ) req.connect("tcp://127.0.0.1:12345") req.send_string("hello") rep.recv() rep.send_string("hallo") req.recv() rep.unbind("tcp://127.0.0.1:12345") rep.close() rep = ctx.socket(zmq.REP) rep.bind("tcp://127.0.0.1:12345") req.send_string("hello") rep.recv() rep.send_string("hallo") req.recv() rep.unbind("tcp://127.0.0.1:12345") rep.close() req.close() rep = ctx.socket(zmq.REP) rep.bind("tcp://127.0.0.1:12345") req = ctx.socket(zmq.REQ) req.setsockopt(zmq.RECONNECT_IVL, -1)req.connect("tcp://127.0.0.1:12345") req.send_string("hello") rep.recv() rep.send_string("hallo") req.recv() rep.unbind("tcp://127.0.0.1:12345") rep.close() rep = ctx.socket(zmq.REP) rep.bind("tcp://127.0.0.1:12345") req.send_string("hello") rep.recv() This last one won't receive the message > > On Sep 1, 2017, at 6:19 PM, Luca Boccassi <luca.bocca...@gmail.com> > > wrote: > > > > On Fri, 2017-09-01 at 18:03 -0400, Bill Torpey wrote: > > > Thanks Luca! That was very helpful. > > > > > > Although it leads to a couple of other questions: > > > > > > - Can I assume that a ZMQ disconnect of a tcp endpoint would only > > > occur if the underlying TCP socket is closed by the OS? Or are > > > there > > > conditions in which ZMQ will proactively disconnect the TCP > > > socket > > > and try to reconnect? > > > > Normally that's the case - you can set up heartbeating with the > > appropriate options and that will kill a connection if there's no > > answer > > > > > - I see that there is a sockopt (ZMQ_RECONNECT_IVL) that can be > > > set > > > to -1 to disable reconnection entirely. In my case, the the > > > “data” > > > socket pair will *always* connect to an ephemeral port, so I > > > *never* > > > want to reconnect. Would this be a reasonable option in my case, > > > do > > > you think? > > > > If that makes sense for your application, go for it - in these > > cases > > the only way to be sure is to test it and see how it works > > > > > - Would there be any interest in a patch that would disable > > > reconnects (controlled by sockopt) for ephemeral ports only? I’m > > > guessing that reconnecting mostly makes sense with well-known > > > ports, > > > so something like this may be of general interest? > > > > If by ephemeral port you mean anything over 1024, then actually in > > most > > applications I've seen it's always useful to reconnect, and the > > existing option should be enough for those cases where it's not > > desired > > - we don't want to duplicate functionality > > > > > Thanks again! > > > > > > Bill > > > > > > > On Sep 1, 2017, at 5:30 PM, Luca Boccassi <luca.boccassi@gmail. > > > > com> > > > > wrote: > > > > > > > > On Fri, 2017-09-01 at 16:59 -0400, Bill Torpey wrote: > > > > > I'm curious about how ZMQ handles re-connection. I > > > > > understand > > > > > that > > > > > re-connection is supposed to happen "automagically" under the > > > > > covers, > > > > > but that poses an interesting question. > > > > > > > > > > To make a long story short, the application I'm working on > > > > > uses > > > > > pub/sub sockets over TCP. and works like follows: > > > > > > > > > > At startup: > > > > > 1. connects to a proxy/broker at a well-known address, using > > > > > a > > > > > pub/sub socket pair ("discovery"); > > > > > 2. subscribes to a well-known topic using the "discovery" > > > > > sub > > > > > socket; > > > > > 3. binds a different pub/sub socket pair ("data") and > > > > > retrieves > > > > > the > > > > > actual endpoints assigned; > > > > > 4. publishes the "data" endpoints from step 3 on the > > > > > "discovery" > > > > > pub > > > > > socket; > > > > > > > > > > When the application receives a message on the "discovery" > > > > > sub > > > > > socket, it connects the "data" socket pair to the endpoints > > > > > specified > > > > > in the "discovery" message. > > > > > > > > > > So far, this seems to be working relatively well, and allows > > > > > the > > > > > high-volume, low-latency "data" messages to be sent/received > > > > > directly > > > > > between peers, avoiding the extra hop caused by a > > > > > proxy/broker > > > > > connection. The discovery messages use the proxy/broker, but > > > > > since > > > > > these are (very) low-volume the extra hop doesn't > > > > > matter. The > > > > > use of > > > > > the proxy also eliminates the "slow joiner" problem that can > > > > > happen > > > > > with other configurations. > > > > > > > > > > My question is what happens when one of the "data" peer > > > > > sockets > > > > > disconnects. Since ZMQ (apparently) keeps trying to > > > > > reconnect, > > > > > what > > > > > would prevent another process from binding to the same > > > > > ephemeral > > > > > port? > > > > > > > > > > - Can I assume that if the new application at that port is > > > > > not a > > > > > ZMQ > > > > > application, that the reconnect will (silently) fail, and > > > > > continue to > > > > > be retried? > > > > > > > > The ZMTP handshake would fail, so yes. > > > > > > > > > - What if the new application at that port *IS* a ZMQ > > > > > application? Would the reconnect succeed? And if so, what > > > > > would > > > > > happen if it's a *DIFFERENT* ZMQ application, and the > > > > > messages > > > > > that > > > > > it's sending/receiving don't match what the original > > > > > application > > > > > expects? > > > > > > > > Depends on how you handle it in your application. If you have > > > > security > > > > concerns, then use CURVE with authentication so that only > > > > authorised > > > > peers can connect. > > > > > > > > > It's reasonable for the application to publish a disconnect > > > > > message > > > > > when it terminates normally, and the connected peers can > > > > > disconnect > > > > > that endpoint. But, applications don't always terminate > > > > > normally > > > > > ;-) > > > > > > > > That's a common pattern. But the application needs to handle > > > > unexpected > > > > data somewhat gracefully. What that means is entirely up to the > > > > application - as far as the library is concerned, if the > > > > handshake > > > > succeeds then it's all good (hence the use case for CURVE). > > > > > > > > > Any guidance, hints or tips would be much appreciated -- > > > > > thanks > > > > > in > > > > > advance! > > > > > > > > -- > > > > Kind regards, > > > > Luca Boccassi_______________________________________________ > > > > zeromq-dev mailing list > > > > zeromq-dev@lists.zeromq.org <mailto:zeromq-dev@lists.zeromq.org > > > > > <mailto:zeromq-dev@lists.zeromq.org <mailto:zeromq-dev@lists. > > > > zeromq.org>> > > > > https://lists.zeromq.org/mailman/listinfo/zeromq-dev > > > > <https://lists.zeromq.org/mailman/listinfo/zeromq-dev> > > > > <https://lists.zeromq.org/mailman/listinfo/zeromq-dev > > > > <https://lists.zeromq.org/mailman/listinfo/zeromq-dev>> > > > > > > _______________________________________________ > > > zeromq-dev mailing list > > > zeromq-dev@lists.zeromq.org <mailto:zeromq-dev@lists.zeromq.org> > > > https://lists.zeromq.org/mailman/listinfo/zeromq-dev > > > <https://lists.zeromq.org/mailman/listinfo/zeromq-dev> > > > > -- > > Kind regards, > > Luca Boccassi_______________________________________________ > > zeromq-dev mailing list > > zeromq-dev@lists.zeromq.org <mailto:zeromq-dev@lists.zeromq.org> > > https://lists.zeromq.org/mailman/listinfo/zeromq-dev > > <https://lists.zeromq.org/mailman/listinfo/zeromq-dev> > > _______________________________________________ > zeromq-dev mailing list > zeromq-dev@lists.zeromq.org > https://lists.zeromq.org/mailman/listinfo/zeromq-dev -- Kind regards, Luca Boccassi
signature.asc
Description: This is a digitally signed message part
_______________________________________________ zeromq-dev mailing list zeromq-dev@lists.zeromq.org https://lists.zeromq.org/mailman/listinfo/zeromq-dev