如何设计扭曲的工厂来处理断开连接?

But*_*840 5 python twisted

我在模块中有一个ReconnectingClientFactory.我希望模块尽可能灵活.我只需要一个TCP连接.我使用工厂作为此连接的持久接口.在过去,工厂会通过无休止地重试连接来响应断开连接,从不通知顶级脚本(导入模块的脚本)存在连接问题.

以下是我所拥有的一个简短示例:

Factory(protocol.ReconnectingClientFactory):

    def clientConnectionFailed(self, connector, reason):
        ...

    def clientConnectionLost(self, connector, reason):
        ...
Run Code Online (Sandbox Code Playgroud)

我认为最好是在出现连接问题时通知顶级脚本(导入模块的脚本).这样,顶级脚本可以定义断开连接解析行为,而不是在模块中对其进行硬编码.但是,将连接问题传达给顶级脚本的最佳方法是什么?

我可以提出异常,但它会被捕获到哪里?我想反应堆会抓住它,但这有什么帮助呢?

没有回调或错误我可以触发通知顶部脚本的连接问题.

顶级脚本可以提供在发生连接问题时要调用的特定函数[作为参数].这是好的设计吗?

Gly*_*yph 3

这个问题有点太抽象了,无法提供直接答案。这取决于您的顶级模块正在做什么。

但是,您应该考虑使用端点,而不是ClientFactory. 这可能会解决您的一些设计问题。接收连接丢失通知有点棘手(因为ClientFactory.clientConnectionLost实际上是 的重复通知IProtocol.connectionLost,它不再存在于端点 API 中;所以IProtocol如果您关心的话,您必须包装该对象),但它确实允许您使用更通用的机制来重试连接失败,而不是,您只是在从 中返回的clientConnectionFailed上得到一个错误返回。因此,例如,如果您想做的只是“不断重新连接直到成功”,您可以使用这个完全通用的-retry-loop 而不是特定于连接的东西,例如:DeferredconnectDeferredReconnectingClientFactory

# Warning, untested, sorry if it's broken.
@inlineCallbacks
def retry(deferredThing, delay=30.0, retryCount=5):
    retries = retryCount
    while True:
        try:
            result = yield deferredThing()
        except:
            if not retries:
                raise
            retries -= 1
            log.err()
            yield deferLater(reactor, delay, lambda : None)
        else:
            returnValue(result)
Run Code Online (Sandbox Code Playgroud)

类似地,如果您可以使该deferredThing函数返回 a ,Deferred则该函数仅在协议的应用程序逻辑完成时才触发,除了调用 、监视之外,IStreamServerEndpoint.connect如果connectionLost在有趣的逻辑完成之前连接丢失,则该函数将失败。

Deferreds可以是跨系统多个级别管理这种异步重试状态的有效方法。