Why is ZeroMQ poller not receiving messages (python)?

孤人 提交于 2021-02-08 08:24:47

问题


I'm trying to use the ZeroMQ Poller() functionality with two sockets in python:

import zmq

# Prepare our context and sockets
context = zmq.Context()

receiver = context.socket(zmq.DEALER)
receiver.connect("ipc:///tmp/interface-transducer")

subscriber = context.socket(zmq.SUB)
subscriber.bind("ipc:///tmp/fast-service")
subscriber.setsockopt(zmq.SUBSCRIBE, b"10001")

# Initialize poll set
poller = zmq.Poller()
poller.register(receiver, zmq.POLLIN)
poller.register(subscriber, zmq.POLLIN)

# Process messages from both sockets
while True:
    try:
        socks = dict(poller.poll())
    except KeyboardInterrupt:
        break

    if receiver in socks:
        message = receiver.recv()
        print("RECEIVER OK\n")

    if subscriber in socks:
        message = subscriber.recv()
        print("SUBSCRIBER OK\n")

And then the server that sends messages as a ROUTER is described as:

def main():
    context = zmq.Context()
    router = context.socket(zmq.ROUTER)
    router.bind("ipc:///tmp/interface-transducer")
    while True:
        identity = b'electrode-service'
        b_identity = identity
        router.send_multipart([b_identity, b'[1,2]'])
        print("Sent")
        time.sleep(1)

if __name__ == "__main__":
    main()

But when I run these two processes, it does not work as expected, the poller-script does not print anything. What could be the problem of such implementation?


回答1:


Q : "What could be the problem of such implementation?"

  • such implementation is prone to deadlock & fails due to using exclusively the blocking-forms of .poll() & .recv() methods

  • such implementation is not self-defending enough in cases, where multiple peers get connected into AccessPoints, that implement round-robin incoming/outgoing traffic mappings

  • such implementation is awfully wrong in standing self-blinded in calling just a single .recv() in cases, where the .send_multipart() is strikingly warning, there will be multi-part message-handling needed

  • ipc:// Transport Class is prone to hide O/S related user-level code restrictions ( placed by the operating system on the format and length of a pathname and effective user-rights to R/W/X there )

  • ipc:// Transport Class .connect()-method's use is order-dependent for cases the target-address has not yet been created by O/S services ( a successful .bind() needs to happen first )

  • last but not least, any next attempt to .bind() onto the same ipc:// Transport Class target will silently destroy your intended ROUTER-access to the messaging/signalling-plane infrastructure & your implementation has spent zero-efforts to self-protect and self-diagnose errors that might silently appear "behind the curtains"

Shouldn't zeromq deal automatically with deadlocks? I tried using the example given in the zeromq guide mspoller If I can't use .poll() and recv() simultaneously, how should I use ZMQ Poller structure? – hao123

No,
ZeroMQ zen-of-zero is performance + low-latency focused, so kindly consider all due care for blocking-prevention to be in your own hands (as needed & where needed, the core lib will never do a single more step than needed for the goal of achieving an almost linear scalable performance ).

No,
use freely both .poll()- & .recv()-methods, yet complete it so as to fit into a non-blocking fashion - .poll( 0 ) & add active detection + handling of multi-part messages ( again, best in a non-blocking fashion, using zmq.NOBLOCK option flag where appropriate ). Self-blocking gets code out of control.



来源:https://stackoverflow.com/questions/64608767/why-is-zeromq-poller-not-receiving-messages-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!