从zmq.PAIR套接字上的zmq.error.Again恢复

时间:2018-03-11 16:50:12

标签: python networking zeromq pyzmq

我有一个客户端使用一对套接字与单个服务器通信:

CommentsController

...

context = zmq.Context()
socket = context.socket(zmq.PAIR)
socket.setsockopt(zmq.SNDTIMEO, 1000)
socket.connect("tcp://%s:%i"%(host,port))

程序每秒发送大约一个10字节的消息。我们看到程序最终会无限期地等待发送消息的问题,所以我们添加了一个SNDTIMEO。但是,现在我们开始获得zmq.error.Again了。一旦我们收到此错误,资源就永远不会再次可用。我正在研究究竟发生了哪些错误代码,但我一般想知道人们用什么技术从程序中的zmq.error.Again中恢复。我应该销毁套接字连接并重新建立吗?

1 个答案:

答案 0 :(得分:1)

事实#0:PAIR/PAIR与其他ZeroMQ原型不同

RFC 31明确定义:

  

此模式的总体目标

     

PAIR 不是通用套接字,而是针对两个对等体在架构上稳定的特定用例。这通常会限制 PAIR 在单个进程中使用,以进行线程间通信。

接下来,如果没有正确设置 SNDHWM 大小,并且意图使用PAIR来操作 tcp:// -transport-class也与所有与操作系统相关的L3 / L2归因,任何下一个 .send() 也会产生 EAGAIN 错误

还有一些额外的反措施( CONFLATE IMMEDIATE HEARTBEAT_{IVL|TTL|TIMEOUT} ),但PAIR/PAIR有上述主要限制,它设定了使用此原型时不会发生的情况。

主要嫌疑人:

鉴于所述设计端限制,损坏的传输路径, PAIR -access-point将不会重新协商将套接字重建为RTO状态。

出于这个原因,如果您的代码确实想要继续使用PAIR/PAIR,那么组装紧急SIG /标记路径可能是明智之举,以便能够在这样的L3 / L2中强有力地生存/ L1事件,PAIR/PAIR已知不会自动处理。

尾声:

您的代码不使用非阻塞.send() - 模式,而 EAGAIN 错误状态恰好用于表示阻止功能(Access的无法使用) - 设置.send()

,此时指向EAGAIN

更好地使用已发布的API详细信息:

aRetCODE = -1 # _______________________________________ PRESET
try:
   aRetCODE = socket.send( msg, zmq.DONTWAIT ) #_______ .SET on RET
   if ( aRetCODE == -1 ):
        ...                                    # ZeroMQ: SIG'd via ERRNO:

except:
   ...                                         #_______ .HANDLE EXC
finally:
   ...