I wrote this
This is a pyzmq bug
What pyzmq version?
27.1.0
What libzmq version?
4.3.5
Python version (and how it was installed)
Python 3.14.3, via pacman
OS
Linux 6.18.18-1-MANJARO
What happened?
The recv and recv_multipart methods for a DISH socket seem to postpone signal handlers until a message is received.
This behaviour differs from the other sockets (have not tested GATHER, SCATTER, DGRAM, PEER and CHANNEL yet), where appropriate signal handlers abort a blocking recv or recv_multipart.
Compare radio.py and dish.py versus the non-draft counterparts pub.py and sub.py:
radio.py
from zmq import Context, RADIO, Frame
from time import sleep
ctx = Context()
socket = ctx.socket(RADIO)
socket.bind("tcp://localhost:5555")
frame = Frame(b"foo")
frame.group = "random"
while True:
print("sending ...")
socket.send(frame, copy=False)
print("sent", frame)
sleep(1)
dish.py
from zmq import Context, DISH
ctx = Context()
socket = ctx.socket(DISH)
socket.connect("tcp://localhost:5555")
socket.join("random")
while True:
print("waiting ...")
frame = socket.recv(copy=False)
assert frame.group == "random"
print("received", frame)
pub.py
from zmq import Context, PUB
from time import sleep
ctx = Context()
socket = ctx.socket(PUB)
socket.bind("tcp://localhost:5555")
frames = [b"random", b"foo"]
while True:
print("sending ...")
socket.send_multipart(frames, copy=False)
print("sent", frames)
sleep(1)
sub.py
from zmq import Context, SUB
ctx = Context()
socket = ctx.socket(SUB)
socket.connect("tcp://localhost:5555")
socket.subscribe("random")
while True:
print("waiting ...")
frames = socket.recv_multipart(copy=False)
print("received", frames)
Run dish.py or sub.py and try to interrupt with Ctrl-C.
dish.py does nothing and continues to run, sub.py prints the traceback of a KeyboardInterrupt and exits.
In case of dish.py, after a Ctrl-C has been hit on it, run radio.py and watch dish.py behave like sub.py but only after is has received a message from radio.py.
More info
The current workaround is to wait for incoming data on the DISH socket via zmq.select or Poller.poll and then call recv or recv_multipart, which then won't block. Both select and Poller.poll don't postpone a signal handler.
I wrote this
This is a pyzmq bug
What pyzmq version?
27.1.0
What libzmq version?
4.3.5
Python version (and how it was installed)
Python 3.14.3, via pacman
OS
Linux 6.18.18-1-MANJARO
What happened?
The
recvandrecv_multipartmethods for aDISHsocket seem to postpone signal handlers until a message is received.This behaviour differs from the other sockets (have not tested GATHER, SCATTER, DGRAM, PEER and CHANNEL yet), where appropriate signal handlers abort a blocking
recvorrecv_multipart.Compare
radio.pyanddish.pyversus the non-draft counterpartspub.pyandsub.py:radio.pydish.pypub.pysub.pyRun
dish.pyorsub.pyand try to interrupt withCtrl-C.dish.pydoes nothing and continues to run,sub.pyprints the traceback of aKeyboardInterruptand exits.In case of
dish.py, after aCtrl-Chas been hit on it, runradio.pyand watchdish.pybehave likesub.pybut only after is has received a message fromradio.py.More info
The current workaround is to wait for incoming data on the
DISHsocket viazmq.selectorPoller.polland then callrecvorrecv_multipart, which then won't block. BothselectandPoller.polldon't postpone a signal handler.