Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop pyzmq receiver by KeyboardInterrupt

Following this example in the ØMQ docs, I'm trying to create a simple receiver. The example uses infinite loop. Everything works just fine. However, on MS Windows, when I hit CTRL+C to raise KeyboardInterrupt, the loop does not break. It seems that recv() method somehow ignores the exception. However, I'd love to exit the process by hiting CTRL+C instead of killing it. Is that possible?

like image 769
Tregoreg Avatar asked Jun 18 '13 16:06

Tregoreg


2 Answers

In response to the @Cyclone's request, I suggest the following as a possible solution:

import signal

signal.signal(signal.SIGINT, signal.SIG_DFL);
# any pyzmq-related code, such as `reply = socket.recv()`
like image 198
Tregoreg Avatar answered Nov 18 '22 09:11

Tregoreg


A zmq.Poller object seems to help:

def poll_socket(socket, timetick = 100):
    poller = zmq.Poller()
    poller.register(socket, zmq.POLLIN)
    # wait up to 100msec
    try:
        while True:
            obj = dict(poller.poll(timetick))
            if socket in obj and obj[socket] == zmq.POLLIN:
                yield socket.recv()
    except KeyboardInterrupt:
        pass
    # Escape while loop if there's a keyboard interrupt.

Then you can do things like:

for message in poll_socket(socket):
    handle_message(message)

and the for-loop will automatically terminate on Ctrl-C. It looks like the translation from Ctrl-C to a Python KeyboardInterrupt only happens when the interpreter is active and Python has not yielded control to low-level C code; the pyzmq recv() call apparently blocks while in low-level C code, so Python never gets a chance to issue the KeyboardInterrupt. But if you use zmq.Poller then it will stop at a timeout and give the interpreter a chance to issue the KeyboardInterrupt after the timeout is complete.

like image 3
Jason S Avatar answered Nov 18 '22 08:11

Jason S