扭曲:回调设计为一个繁琐的协议

时间:2013-07-12 11:53:39

标签: python twisted

我正在使用twisted来处理基于文本的协议。最初客户端连接到服务器。连接后,服务器将发送客户端应响应的命令。每种类型的命令都需要不同的时间来制定响应。 (例如:从本地哈希返回值而不是从大型数据库上的复杂MySQL查询返回值)。客户端的响应应按接收命令的顺序进行。在发送另一个命令之前,服务器不会等待来自一个命令的响应,但是期望在命令命令中发送响应。客户端不能指望从服务器发送命令的任何顺序。

以下是一个最小代码,显示了我的程序当前的工作方式。

class ExternalListener(LineReceiver):
    def connectionMade(self):
        log.msg("Listener: New connection")

    def lookupMethod(self, command):
        return getattr(self, 'do_' + command.lower(), None)

    def lineReceived(self, verb):
        method = self.lookupMethod(verb)
        method(verb)

    def do_cmd1(self, verb):
        d = self.getResult(verb)
        d.addCallback(self._cbValidate1)

    def _cbValidate1(self):
        resp = "response"
        self.transport.write(resp)

    def do_cmd2(self, verb):
        d = self.getResult(verb)
        d.addCallback(self._cbValidate1)

    def _cbValidate2(self):
        resp = "response"
        self.transport.write(resp)

可以看出,这不会处理响应的排序。我无法使用DeferredList,因为延迟是在收到命令时创建的,并且没有延迟列表可以放在DeferredList中。

处理这种情况的 twisted 方法是什么?

谢谢和问候,

1 个答案:

答案 0 :(得分:1)

一种解决方案是使用带有标记的协议来处理请求和响应。这意味着您可以按任何顺序生成响应。请参阅AMP(或甚至IMAP4)作为此类协议的示例。

但是,如果协议不在您的控制之下并且您无法修复它,那么一个不太好的解决方案是缓冲响应以确保正确的排序。

我认为这里没有任何特别的 Twisted 解决方案,只需要在发送旧请求的所有响应之前保留对较新请求的响应。这可能是在内部使用计数器为响应分配排序然后实现逻辑以在需要等待或发送响应时缓冲响应以及如果不需要则缓冲所有适当的缓冲响应的问题。