[zeromq-dev] "Wakeup call" to a thread blocked inside zmq_poll()?

Michel Pelletier pelletier.michel at gmail.com
Mon Aug 13 20:59:24 CEST 2012


Using a waker socket is a great approach like MinRK said, FWIW it's
not necessary to create a push and a pull socket, a single DEALER
socket can connect to itself.  Here's a tweak of MinRK's diff:

https://gist.github.com/3343232

Lately I've been on a tirade of deprecating PUSH/PULL in my code in
favor of DEALER in all cases, this looks like another nice case.

-Michel

On Mon, Aug 13, 2012 at 11:49 AM, MinRK <benjaminrk at gmail.com> wrote:
>
> On Mon, Aug 13, 2012 at 11:05 AM, Arthur O'Dwyer <arthur at push.am> wrote:
>>
>> Hi all,
>>
>> I'm trying to use ZMQ in what I guess (surprisingly to me) is an
>> unconventional way. The salient points of our protocol are:
>>
>> - The connection has only two ends: exactly one client and exactly one
>> server.
>>
>> - In fact, the labels "client" and "server" are mostly unnecessary;
>> requests can originate on either side. Sometimes the client asks the
>> server something, and sometimes the server asks the client something.
>>
>> - Answers to questions don't come right away (requests and replies are
>> not nicely nested). If the client has two things to ask the server, it
>> can do both requests at once, and the server can spawn two worker
>> threads to compute the answers in parallel.
>>
>> I believe the architecture we need is a work queue on each side: when
>> a client thread asks a question, it puts a request packet P_a and a
>> timeout value T_a into the "outbox" and then waits on a condition
>> variable associated with that transaction-ID. There's a master ZMQ
>> thread with three responsibilies:
>>
>>     - Whenever the outbox is non-empty, pull a message from it and
>> send it over the wire.
>>     - Whenever a request comes in over the wire, spawn a new worker
>> thread to handle that request.
>>     - Whenever a reply comes in over the wire, match its
>> transaction-ID to our list of waiting workers and notify the worker
>> who's waiting for this particular reply.
>>     - T_a seconds after the request P_a goes out over the wire, if the
>> reply hasn't come yet, notify the waiting worker that the reply has
>> timed out.
>>
>> Also, we'd like to have a "heartbeat" in both directions. But I
>> believe that can easily be handled as a special kind of worker thread
>> on each side, whose only job is to send a request every N seconds and
>> complain if the reply times out.
>>
>> This feels like a really simple and common architecture, and I also
>> believe it would work out of the box if ZMQ supported calling
>> zmq_poll() from multiple threads (because then we wouldn't even need
>> the master thread; all of this queuing ickiness would happen inside
>> ZMQ itself). But for the life of me I can't figure out how to get ZMQ
>> to wait on "something is incoming over the wire *or*
>> some-other-event", without just polling every millisecond inside a
>> loop.
>>
>> Suppose Thread A is waiting inside zmq_poll(); is there any way for
>> Thread B to say "Hey! Wake up right now! I need to send a message!"?
>
>
> You can do this by creating a waker socket just for this purpose, and always
> including it in the poll set:
>
> https://gist.github.com/3343165
>
> -MinRK
>
>
>>
>>
>> Thanks much,
>> -Arthur
>> _______________________________________________
>> 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