Pyzmq high-water mark not working on pub socket

后端 未结 1 525
[愿得一人]
[愿得一人] 2020-12-21 19:22

According to the ZeroMQ documentation a pub socket is supposed to drop messages once the number of queued messages reaches the high-water mark.

This doesn\'t seem to

相关标签:
1条回答
  • 2020-12-21 20:11

    With borrowing an answer to the issue which I opened in Github, I've updated my answer as follows:


    Messages are held in operating system's network buffers. I have found HWMs to be not that useful because of that. Here is modified code where subscriber misses messages:

    import time
    import pickle
    import zmq
    from threading import Thread
    import os
    
    ctx = zmq.Context()
    
    def pub_thread():
        pub = ctx.socket(zmq.PUB)
        pub.setsockopt(zmq.SNDHWM, 2)
        pub.setsockopt(zmq.SNDBUF, 2*1024)  # See: http://api.zeromq.org/4-2:zmq-setsockopt
        pub.bind('tcp://*:5555')
        i = 0
        while True:
            time.sleep(0.001)
            pub.send_string(str(i), zmq.SNDMORE)
            pub.send(os.urandom(1024))
            i += 1
    
    def sub_thread():
        sub = ctx.socket(zmq.SUB)
        sub.setsockopt(zmq.SUBSCRIBE, b'')
        sub.setsockopt(zmq.RCVHWM, 2)
        sub.setsockopt(zmq.RCVBUF, 2*1024)
        sub.connect('tcp://localhost:5555')
        while True:
            time.sleep(0.1)
            msg, _ = sub.recv_multipart()
            print("Received:", msg.decode())
    
    t_pub = Thread(target=pub_thread)
    t_pub.start()
    sub_thread()
    

    Output looks something like this:

    Received: 0
    Received: 1
    Received: 2
    Received: 3
    Received: 4
    Received: 5
    Received: 6
    Received: 47
    Received: 48
    Received: 64
    Received: 65
    Received: 84
    Received: 85
    Received: 159
    Received: 160
    Received: 270
    

    Messages are missed because all queues/buffers are full and publisher starts to drop messages (see documentation for ZMQ_PUB: http://api.zeromq.org/4-2:zmq-socket).


    [NOTE]:

    • You should use the high-water mark option in listener/subscriber and advertiser/publisher.
    • These posts are also relevant (Post1 - Post2)
    • sock.setsockopt(zmq.CONFLATE, 1) is another option to get the last message only which defined in subscriber side.
    0 讨论(0)
提交回复
热议问题