How does zmq poller work?

user1876508 picture user1876508 · Aug 7, 2013 · Viewed 23.3k times · Source

I am confused as to what poller actually does in zmq. The zguide goes into it minimally, and only describes it as a way to read from multiple sockets. This is not a satisfying answer for me because it does not explain how to have timeout sockets. I know zeromq: how to prevent infinite wait? explains for push/pull, but not req/rep patterns, which is what I want to know how to use.

What I am attempting to ask is: How does poller work, and how does its function apply to keeping track of sockets and their requests?

Answer

raffian picture raffian · Aug 8, 2013

When you need to listen on different sockets in the same thread, use a poller:

ZMQ.Socket subscriber = ctx.socket(ZMQ.SUB)
ZMQ.Socket puller = ctx.socket(ZMQ.PULL)

Register sockets with poller (POLLIN listens for incoming messages)

ZMQ.Poller poller = ZMQ.Poller(2)
poller.register(subscriber, ZMQ.Poller.POLLIN)
poller.register(puller, ZMQ.Poller.POLLIN)

When polling, use a loop:

while( notInterrupted()){
  poller.poll()

  //subscriber registered at index '0'
  if( poller.pollin(0)) 
     subscriber.recv(ZMQ.DONTWAIT)

  //puller registered at index '1'
  if( poller.pollin(1))
     puller.recv( ZMQ.DONTWAIT)
}

Choose how you want to poll...

poller.poll() blocks until there's data on either socket.
poller.poll(1000) blocks for 1s, then times out.

The poller notifies when there's data (messages) available on the sockets; it's your job to read it.

When reading, do it without blocking: socket.recv( ZMQ.DONTWAIT). Even though poller.pollin(0) checks if there's data to be read, you want to avoid any blocking calls inside the polling loop, otherwise, you could end up blocking the poller due to 'stuck' socket.

So, if two separate messages are sent to subscriber, you have to invoke subscriber.recv() twice in order to clear the poller, otherwise, if you call subscriber.recv() once, the poller will keep telling you there's another message to be read. So, in essence, the poller tracks the availability and number of messages, not the actual messages.

You should run through the polling examples and play with the code, it's the best way to learn.

Does that answer your question?