简体   繁体   English

ZeroMQ Pub / Sub动作队列中的最后一个元素和其他元素

[英]ZeroMQ Pub/Sub action last element in queue an other elements

I started using zeromq with python with the Publisher/Subscriber reference. 我开始在发布者/订阅者引用中使用带有python的zeromq However, I don't find any documentation about how to treat messages in the queue. 但是,我找不到有关如何处理队列中的消息的任何文档。 I want to treat the last received message different as the rest of the elements of the queue. 我想将最后收到的消息视为队列的其余元素。

Example

publisher.py publisher.py

import zmq
import random
import time

port = "5556"
topic = "1"

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:%s" % port)

while True:
    messagedata = random.randrange(1,215)
    print "%s %d" % (topic, messagedata)
    socket.send("%s %d" % (topic, messagedata))
    time.sleep(.2)

subscriber.py subscriber.py

import zmq

port = "5556"
topic = "1"

context = zmq.Context()
socket = context.socket(zmq.SUB)

print "Connecting..."
socket.connect ("tcp://localhost:%s" % port)
socket.setsockopt(zmq.SUBSCRIBE,topic)

while True:
    if isLastMessage(): # probably based on socket.recv()
         analysis_function() # time consuming function
    else:
         simple_function()  # something simple like print and save in memory

I just want to know how to create the isLastMessage() function described in the subscriber.py file. 我只想知道如何创建subscriber.py文件中描述的isLastMessage()函数。 If there's something directly in zeromq or a workaround. 如果有一些直接在zeromq或解决方法的东西。

Welcome to the world of non-blocking messaging / signalling 欢迎来到无阻塞消息/信令的世界

this is a cardinal feature for any serious distributed-system design. 这是任何严肃的分布式系统设计的基本功能。

If you assume a "last" message via a not having another one in the pipe, then a Poller() instance may help your main event-loops, where you may control the amount of time to "wait"-a-bit before considering the pipe "empty", not to devastate your IO-resources with zero-wait spinning-loops. 如果您通过管道中没有另一个消息来假设“最后”消息,则Poller()实例可以帮助您的主事件循环,您可以在考虑之前“等待”-a-bit的时间量管道“空”,不要用零等待旋转循环来破坏你的IO资源。

Explicit signalling is always better ( if you can design the remote end behaviour ) 显式信令总是更好(如果你可以设计远程端行为)

There is Zero-knowledge on the receiver-side, what is the context of the "last"-message received ( and explicit signalling is advised to be rather broadcast from the message sender-side ), however there is a reversed feature to this -- that instructs ZeroMQ archetypes to "internally"-throw away all such messages, that are not the "last"-message, thus reducing the receiver-side processing to right the "last"-message available. 接收方有零知识,接收到的“最后”消息的上下文是什么(建议显式信令从消息发送方广播),但是有一个相反的特征 - - 指示ZeroMQ原型“内部” - 丢弃所有这些不是“最后”消息的消息,从而将接收方处理减少到正确的“最后”消息。

aQuoteStreamMESSAGE.setsockopt( zmq.CONFLATE, 1 )

If you may like to read more on ZeroMQ patterns and anti-patterns, do not miss Pieter HINTJENS' fabulous book "Code Connected, Volume 1" ( also in pdf ) and may like a broader view on using principally a non-blocking ZeroMQ approach 如果您想了解有关ZeroMQ模式和反模式的更多信息,请不要错过Pieter HINTJENS的精彩书籍“Code Connected,Volume 1”(也在pdf中),并且可能更喜欢使用主要 阻止ZeroMQ方法

If isLastMessage() is meant to identify the last message within the stream of messages produced by publisher.py , than this is impossible since there is no last message. 如果isLastMessage()用于标识publisher.py生成的消息流中的最后一条消息,那么这是不可能的,因为没有最后一条消息。 publisher.py produces an infinite amount of messages! publisher.py生成无限量的消息!

However, if publisher.py knows its last "real" message, ie no while True: , it could send a "I am done" message afterwards. 但是,如果publisher.py知道它的最后一条“真实”消息,即while True:没有,则它可以在之后发送“我完成”消息。 Identifying that in subscriber.py is trivial. subscriber.py识别它是微不足道的。

Sorry, I will keep the question for reference. 对不起,我会保留这个问题以供参考。 I just found the answer, in the documentation there is a NOBLOCK flag that you can add to the receiver. 我刚刚找到答案,在文档中有一个NOBLOCK标志,你可以添加到接收器。 With this the recv command doesn't block. 使用此命令, recv命令不会阻止。 A simple workaround, extracted from a part of an answe r, is the following: answe的一部分中提取的简单解决方法如下:

while True:
    try:
        #check for a message, this will not block
        message = socket.recv(flags=zmq.NOBLOCK)

        #a message has been received
        print "Message received:", message

    except zmq.Again as e:
        print "No message received yet"

As for the real implementation, one is not sure that it is the last call you use the flag NOBLOCK and once you have entered the exception block. 至于真正的实现,一旦你输入了exception块,就不能确定它是你使用标志NOBLOCK的最后一次调用。 Wich translates to something like the following: 这转换成如下内容:

msg = subscribe(in_socket)
is_last = False
while True:
    if is_last:
        msg = subscribe(in_socket)
        is_last = False
    else:
        try:
            old_msg = msg
            msg = subscribe(in_socket,flags=zmq.NOBLOCK)
            # if new message was received, then process the old message
            process_not_last(old_msg)
        except zmq.Again as e:
            process_last(msg)
            is_last = True  # it is probably the last message

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM