[zeromq-dev] Failing to synchronize 0mq sockets
Michel Pelletier
pelletier.michel at gmail.com
Tue Apr 3 16:34:11 CEST 2012
On Tue, Apr 3, 2012 at 4:16 AM, Daniele Varrazzo
<daniele.varrazzo at gmail.com> wrote:
> On Tue, Apr 3, 2012 at 7:36 AM, Michel Pelletier
> <pelletier.michel at gmail.com> wrote:
>> Your example works fine for me if you change the tcp PUB endpoint
>> transport to inproc.
>
> This means that it doesn't work, does it? I mean, my program
> establishes an unequivocal temporal sequence, that somehow is not
> respected. I wonder why, as it makes syncing impossible even with the
> best intentions. If it works using inproc and not other transports I
> assume it only does by implementation accident.
It works, you just have to compare apples to apples. A tcp connect
can take several milliseconds, an inproc connect is essentially a
no-op. Your thread sync is not the performance critical part of your
program, why not just switch it to tcp, or switch the publisher to
inproc? What's the point of publishing externally but synchronizing
internally? If you use the same transports for pub and sync, and more
closely follow the synchronized subscriber pattern in the gude (using
REQ/REP, not PAIR) everything will work fine, and if you use a process
approach instead of threads you can scale beyond a core or two.
> More or less this is the same conclusion I've reached: that connect()
> doesn't block and returns before really establishing a connection.
Yep, it's asynchronous, that's a feature. Since you're using
eventlet, I imagine you can understand how that's a benefit to you in
the sense that it doesn't block your eventlet io loop. Also, either
end of a zmq connection can bind and the other connect. Once
established, the two endpoints are peers, it matters not which one was
initially "binding" and the other "connecting" and to make that
happen, connect needs to succeed without guarantee that the endpoint
it is connecting to is bound yet.
> But
> in this case how can you write a correct program using zmq? Is this a
> design decision or an unexpected behaviour?
It's exactly expected, your problem is synchronizing one transport
with another. Unify them an you will have no problems. inproc and
PAIR is fine for purely internal communication between threads, but
that's not what your doing, you're trying to sync to what is
essentially an external resource with an internal mechanism.
> I mostly share your view about the approach to concurrency in Python.
> I am studying zmq exactly in the view of eventlet integration (which
> is not as straightforward as I'd have expected: you can't use the
> poller, apparently you can't use devices...).
That's because eventlet has its own "event loop". There's no need for
zmq.poll because eventlet is in charge of what happens when. I don't
know much about eventlet, but it's likely you can tell it to "switch"
threads on zmq events by passing the eventlet loop a file descriptor
for a zmq socket. This is a pretty advanced pattern. Check out the
gevent_zeromq integration in pypi for a great example of a very
elegant way to integrate zeromq with an green thread system like
eventlet.
-Michel
More information about the zeromq-dev
mailing list