【问题标题】:Stopping task.LoopingCall if exception occurs如果发生异常则停止 task.LoopingCall
【发布时间】:2014-07-13 20:57:31
【问题描述】:

我是 Twisted 的新手,在最终弄清楚延迟的工作方式之后,我正在努力完成这些任务。我想要实现的是有一个在循环中发送 REST 请求的脚本,但是如果在某些时候它失败了,我想停止循环。由于我正在使用回调,因此我无法轻松捕获异常,并且因为我不知道如何停止从 errback 循环,所以我被卡住了。

这是我的代码的简化版本:

def send_request():
    agent = Agent(reactor)
    req_result = agent.request('GET', some_rest_link)
    req_result.addCallbacks(cp_process_request, cb_process_error)

if __name__ == "__main__":
    list_call = task.LoopingCall(send_request)
    list_call.start(2)
    reactor.run()

【问题讨论】:

    标签: python twisted twisted.internet


    【解决方案1】:

    要结束task.LoopingCall,您只需在返回对象上调用stop(在您的情况下为list_call)。

    您需要以某种方式使该 var 可用于您的 errback (cb_process_error),方法是通过将其推送到 cb_process_error 所在的类中,通过用作伪全局的其他类或通过字面上使用全局,那么你只需在 errback 中调用list_call.stop()

    顺便说一句:

    由于我使用回调,我无法轻松捕获异常

    这不是真的。处理异常的 errback 的意义在于,这就是导致它被调用的原因之一!看看我之前的deferred answer,看看它是否让 errbacks 更清晰。

    以下是一个可运行的示例(...我并不是说这是最好的方法,只是说它是一种方法... )

    #!/usr/bin/python
    
    from twisted.internet import task
    from twisted.internet import reactor
    from twisted.internet.defer import Deferred
    from twisted.web.client import Agent
    from pprint import pprint
    
    class LoopingStuff (object):
    
        def cp_process_request(self, return_obj):
            print "In callback"
            pprint (return_obj)
    
        def cb_process_error(self, return_obj):
            print "In Errorback"
            pprint(return_obj)
            self.loopstopper()
    
        def send_request(self):
            agent = Agent(reactor)
            req_result = agent.request('GET', 'http://google.com')
            req_result.addCallbacks(self.cp_process_request, self.cb_process_error)
    
    def main():
        looping_stuff_holder = LoopingStuff()
        list_call = task.LoopingCall(looping_stuff_holder.send_request)
        looping_stuff_holder.loopstopper = list_call.stop
        list_call.start(2)
        reactor.callLater(10, reactor.stop)
        reactor.run()
    
    if __name__ == '__main__':
      main()
    

    假设您可以到达 google.com,这将获取页面 10 秒,如果您将 agent.request 的第二个参数更改为 http://127.0.0.1:12999 之类的东西(假设端口 12999 将拒绝连接),那么您将看到 1 个 errback 打印输出(这也将关闭循环调用)并等待 10 秒,直到反应堆关闭。

    【讨论】:

    • 我知道 stop 方法,但是当连接终止时也会调用 errback。有没有一种简单的方法可以区分成功连接与终止连接和 errback 中的失败连接?
    • 关闭时调用errback???您需要在问题中提供更多代码。通常关闭只是调用你的protocols connectionLost 并且不会触发延迟,我很困惑你的情况是如何发生的。您可以在this prev answer中的示例代码中看到我正在谈论的关闭样式
    • 等等,你是在专门讨论agent.request 电话吗? (即您自己没有与listenTCP 等建立联系)我为扭曲的代码给出了更通用的答案。
    • 是的,我说的是agent.request。请忽略我关于连接关闭时触发 errback 的评论,这是我的错误。
    • 是的,刚刚编写了示例代码,我只是在连接错误时得到 errback,否则只有得到回调。我会在一分钟内将代码添加到我的答案中。
    猜你喜欢
    • 2016-05-30
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多