0

I have python server that waits for a global flag to be set and exits.

In a few threads, I have code that waits using zmq.Poller for a message. It times out, prints a heartbeat message, then waits on poller for a new message:

def timed_recv(zock, msec=5000.0):
    poller = zmq.Poller()
    poller.register(zock, zmq.POLLIN)
    events = dict(poller.poll(msec))
    data = None
    if events and events.get(zock) == zmq.POLLIN:
        # if a message came in time, read it.
        data = zock.recv()
    return data

So in the above function, I wait for 5 seconds for a message to arrive. If none does, the function returns, the calling loop prints a message and waits for a new message:

while not do_exit():
    timed_recv(zock)
    print "Program still here!"
sys.exit()

do_exit() checks a global flag for exitting.

Now, if the flag is set, there can be a 5 second delay between it being set, and the loop exitting. How, can I poll for both zock input, and for the global flag being set so that the loop exits quickly?

I thought I can add to the poller, a file descriptor that closes upon global flag being set. Does that seem reasonable? It seems kind of hackish.

Is there a better way to wait for global flag and POLLIN on zock?

(We are using zmq version 3.0 on debian.)

thanks.

Bitdiot
  • 1,506
  • 2
  • 16
  • 30

1 Answers1

1

The easiest way is to drop the use of a flag, and use another 0mq socket to convey a message. The poller can then wait on both 0mq sockets. The message could be just a single byte; it's arrival in the poller is the message, not its content.

In doing that you're heading down the road to Actor Model programming.

It's a whole lot easier if a development sticks to one programming model; mixing stuff up (e.g. 0mq and POSIX condition variables) is inviting a lot of problems.

bazza
  • 7,580
  • 15
  • 22
  • Thanks for your response. Of course it's easier, but most programming projects are not started from scratch. We are retrofitting zmq into our existing code. Anyways, I will most likely refactor to use zmq, but I need to examine all the places where this would need to be done. I've ended up using zmq, but there are other thread like 'use - patterns' which will need to be converted. – Bitdiot Nov 23 '15 at 14:30
  • 2
    @Bitdiot, you're welcome. Good luck! 0mq is a good choice, with nanomsg being another option. Nanomsg is a better architecture than 0mq, but is younger and still in beta; are you feeling brave?! Once you've completely converted your code you will end up with something much more scalable. It is worth adding a way of configuring the connection strings and which threads are run. Then you can deploy your program across a single or multiple networked machines with no changes except that configuration. Neat! – bazza Nov 24 '15 at 05:49
  • 1
    @Bitdiot, regarding replace the flag, the pattern best suited to that would be a pub-sub, assuming that there is a single thread setting the flag. – bazza Nov 24 '15 at 05:52