def test_eintr_retry_zmq(itimer, signo, socket, addr): push = socket(zmq.PUSH) pull = socket(zmq.PULL) link_sockets(addr, push, [pull]) interrupted_frames = [] def handler(signo, frame): interrupted_frames.append(frame) prev_handler = signal.signal(signo, handler) prev_itimer = signal.setitimer(itimer, 0.001, 0.001) for x in itertools.count(): eintr_retry_zmq(push.send, bytes(x)) assert eintr_retry_zmq(pull.recv) == bytes(x) if len(interrupted_frames) > 100: break signal.setitimer(itimer, *prev_itimer) signal.signal(signo, prev_handler)
def recv(socket, flags=0, capture=(lambda msgs: None)): """Receives header, payload, and topics through a ZeroMQ socket. :param socket: a zmq socket. :param flags: zmq flags to receive messages. :param capture: a function to capture received messages. """ msgs = eintr_retry_zmq(socket.recv_multipart, flags) capture(msgs) return parse(msgs)
def send(socket, header, payload, topics=(), flags=0): """Sends header, payload, and topics through a ZeroMQ socket. :param socket: a zmq socket. :param header: a list of byte strings which represent a message header. :param payload: the serialized byte string of a payload. :param topics: a chain of topics. :param flags: zmq flags to send messages. """ msgs = [] msgs.extend(topics) msgs.append(SEAM) msgs.extend(header) msgs.append(payload) return eintr_retry_zmq(socket.send_multipart, msgs, flags)
def recv(socket, flags=0, capture=(lambda msgs: None)): """Receives header, payload, and topics through a ZeroMQ socket. :param socket: a zmq socket. :param flags: zmq flags to receive messages. :param capture: a function to capture received messages. """ msgs = eintr_retry_zmq(socket.recv_multipart, flags) capture(msgs) try: seam = msgs.index(SEAM) except ValueError: raise EOFError("no seam after topics") if seam == len(msgs) - 1: raise EOFError("neither header nor payload") topics = msgs[:seam] header = msgs[seam + 1 : -1] payload = msgs[-1] return header, payload, topics