Bra*_*des 20 python concurrency rpc message-queue zeromq
我本周开始使用ZeroMQ,当使用请求 - 响应模式时,我不确定如何让工作人员安全地"挂断"并关闭他的套接字而不可能丢弃消息并导致发送该消息的客户永远不会得到响应.想象一下用Python编写的工人看起来像这样:
import zmq
c = zmq.Context()
s = c.socket(zmq.REP)
s.connect('tcp://127.0.0.1:9999')
while i in range(8):
s.recv()
s.send('reply')
s.close()
Run Code Online (Sandbox Code Playgroud)
我一直在做实验,并且发现一个127.0.0.1:9999套接字类型的客户zmq.REQ做出一个公平排队的请求可能会让公司排队算法在工人完成最后一次工作之后send()但在工作之前就选择上面的工作人员.以下close()方法.在这种情况下,似乎请求由工作进程中的ØMQ堆栈接收和缓冲,并且当close()抛出与套接字关联的所有内容时请求将丢失.
工人如何"安全"分离 - 有没有办法发出"我不再需要消息"的信号,然后(a)循环传输信号期间到达的任何最终消息,(b)生成他们的回复,然后(c)执行close()保证不丢弃任何消息?
编辑:我想我想要输入的原始状态是"半封闭"状态,没有进一步的请求可以接收 - 并且发送者会知道 - 但返回路径仍然打开,以便我可以检查我的传入缓冲区是一个最后到达的消息,如果有一个坐在缓冲区中则响应它.
编辑:在回答一个好问题时,更正了描述以使等待消息的数量为多个,因为可能有许多连接在等待回复.
Sam*_*ieu 11
你似乎认为你试图避免像"in"这样的"简单"竞争条件
... = zmq_recv(fd);
do_something();
zmq_send(fd, answer);
/* Let's hope a new request does not arrive just now, please close it quickly! */
zmq_close(fd);
Run Code Online (Sandbox Code Playgroud)
但我认为问题在于公平排队(循环)会让事情变得更加困难:你甚至可能已经对你的工作人员提出了几个排队请求.如果轮到收到新请求,发送方将不会等待您的工作人员在发送新请求之前获得空闲,因此在您拨打zmq_send其他请求时可能已经在等待.
事实上,您可能选择了错误的数据方向.您可能希望让您的工作人员从请求队列中获取新请求,处理它,然后发送答案,而不是让请求池向您的工作人员发送请求(即使您不希望接收新请求).
当然,这意味着使用XREP/ XREQ,但我认为这是值得的.