使用DeferredQueue进行Twisted中的任务间通信

时间:2013-09-27 15:02:19

标签: python asynchronous twisted deferred

我有一位客户目前正在执行以下操作:

  1. 所连接
  2. 在本地收集一些数据
  3. 将该数据发送到服务器
  4. 重复
  5. 如果断开连接,则重新连接并继续上述(未显示)
  6. 像这样:

    def do_send(self):
        def get_data():
            # do something
            return data
    
        def send_data(data)
            self.sendMessage(data)
    
        return deferToThread(get_data).addCallback(send_data)
    
    def connectionMade(self):
        WebSocketClientProtocol.connectionMade(self)
        self.sender = task.LoopingCall(self.do_send)
        self.sender.start(60)
    

    然而,当断开连接时,我希望数据收集能够继续,可能在一定限度内排队并写入文件。我已经查看了DeferredQueue对象,它看起来像我需要的东西,但我似乎无法破解它。

    在伪代码中,它会是这样的:

    queue = DeferredQueue
    
    # in a separate class from the client protocol
    def start_data_collection():
        self.collecter = task.LoopingCall(self.get_data)
        self.sender.start(60)
    
    def get_data()
        # do something
        queue.put(data)
    

    然后让客户端协议检查队列,这是我迷路的地方。 DeferredQueue是我需要的,还是有更好的方法?

1 个答案:

答案 0 :(得分:2)

列表也可以正常工作。你可能会迷失在同一个地方 - 你如何检查列表中的客户端协议?

无论哪种方式,这是一个答案:

queued = []

...

connecting = endpoint.connect(factory)
def connected(protocol):
    if queued:
        sending = protocol.sendMessage(queued.pop(0))
        sending.addCallback(sendNextMessage, protocol)
        sending.addErrback(reconnect)
connecting.addCallback(connected)

这里的想法是,在某些时候发生事件:您的连接已建立。此示例将该事件表示为connecting Deferred。事件发生时,会调用connected。此示例弹出队列中的第一个项目(list)并发送它。它等待发送被确认,然后发送下一条消息。它还暗示了一些关于通过重新连接来处理错误的逻辑。

您的代码可能看起来不同。您可以使用Protocol.connectionMade回调来代表连接事件。核心思想是相同的 - 定义回调以在事件发生时处理它们。无论您使用端点的connect Deferred还是协议的connectionMade都无关紧要。