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

Arthur O'Dwyer arthur at push.am
Mon Aug 13 20:05:12 CEST 2012


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!"?

Thanks much,
-Arthur



More information about the zeromq-dev mailing list