【问题标题】:gevent 'with Timeout' stopped workinggevent“超时”停止工作
【发布时间】:2012-10-16 12:06:32
【问题描述】:

我已从 gevent 13.x 升级到 1.0b4。

我有故障转移代码,通过每 5 秒发送一次“HUGZ”来检查连接是否仍然有效。如果 HUGZ 未能到达,则建立到不同位置的替代连接。此故障转移机制停止工作,因为超时行为发生了变化。

我用with Timeout 做了一些测试代码,它按预期工作, 但是完全相同的代码在我的应用程序上下文中不再起作用。故障转移代码以前可以工作。

我正在使用 gevent-zeromq 接收 with TimeOut 块中的消息,但 with TimeOut 块,并且永远不会“超时”并继续执行,因此恢复代码不会被执行。

什么可能导致超时机制不起作用? 以前有效的超时代码不再有效。

if active_socket:
    print 'waiting for message'

    with Timeout(2, False):
        node_message = NodeMessage.recv(active_socket)

    When no message arrives in time, the code block after this text 
    does not get executed. and it should!! and did before.


    logging.info('ping..')
    logging.info(node_message.name)

    # deal with message from plc_server.
    if node_message:
        handle_node_message(plc_client, plc_server, node_message)
    else:
       # no nodemessage or hugz recieved.
       # plc_server has died a horrible death? reboot?

recv 方法:

  @classmethod
  def recv(cls, socket):
      """Reads name-value message from socket"""

      while True:
          message = socket.recv()
          if message:
              return cls.from_message(message)

套接字是在我有几个连接对象中初始化的:

 from gevent import Timeout
 from gevent_zeromq import zmq

 ..yada yada yada...

    self.subscriber = ctx.socket(zmq.SUB)
    self.subscriber.setsockopt(zmq.SUBSCRIBE, '')
    self.subscriber.connect('%s:%d' % (address, port + 1))
    self.subscriber.linger = 0

蛋黄:

gevent-zeromq   - 0.2.5        - active 
gevent          - 1.0b4        - active 
greenlet        - 0.4.0        - active 

【问题讨论】:

    标签: python gevent


    【解决方案1】:

    改变:

    with Timeout(2, False):
        node_message = NodeMessage.recv(active_socket)
    

    到:

    class MessageContext(object):
        node_message = None
    
    messageContext = MessageContext()  //shared memmory between greenlets
    
    ...
    
    def get_next_message(active_socket)
        messageContext.node_message = NodeMessage.recv(active_socket)
    
    with Timeout(2, False):
         ..putting the actual receving of a message in its own greenlet
         ..makes TimeOut failover/Timeout work again..
    
        gevent.spawn(get_next_message, active_socket).job()
    
    node_message = messageContext.node_message
    

    【讨论】:

    • 为什么 'recv()' 之前有收益,而现在没有?
    • 我猜 'recv()' 确实产生了,否则我的整个应用程序会阻塞,而这并没有发生。我查看了gevent中的TimeOut代码,发现代码很长时间没有变化。所以我猜它与 zmq/gevent_zmq 有关。
    猜你喜欢
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 2016-09-10
    • 2022-07-10
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多