【问题标题】:Twisted Python pause/postpone reactor扭曲的 Python 暂停/延迟反应器
【发布时间】:2013-12-23 16:54:23
【问题描述】:

我对 twisted 很陌生,我有一个 HTTP 客户端,它查询一个有速率限制的服务器,当我达到这个限制时,服务器响应 HTTP 204,所以当我处理响应时,我可能正在做一些讨厌的东西,像这样:

def handleResponse(r, ip):
if r.code == 204:
    print 'Got 204, sleeping'
    time.sleep(120)
    return None
else:
    jsonmap[ip] = ''
    whenFinished = twisted.internet.defer.Deferred()
    r.deliverBody(PrinterClient(whenFinished, ip))
    return whenFinished

我这样做是因为我想暂停所有任务。

我想到了两种行为,要么在同一执行中重新运行之后达到 204 的任务(不知道是否可能),要么只记录错误并在之后重新运行它们在程序的另一次执行中。另一个可能引发的问题是,如果服务器没有响应,我已经在连接上设置了超时,以便在预定义的时间后取消延迟(参见下面的代码)

timeoutCall = reactor.callLater(60, d.cancel)
def completed(passthrough):
    if timeoutCall.active():
        timeoutCall.cancel()
    return passthrough
d.addCallback(handleResponse, ip)
d.addErrback(handleError, ip)
d.addBoth(completed)

我可能遇到的另一个问题是,如果我正在睡觉,我可能会遇到此超时,并且我的所有请求都将被取消。

我希望我已经足够精确了。 提前谢谢你。

杰波

【问题讨论】:

    标签: python twisted reactor


    【解决方案1】:

    不要在任何基于 Twisted 的代码中使用 time.sleep(20)。这违反了您可能正在使用的任何其他基于 Twisted 的代码所做的基本假设。

    相反,如果想延迟 N 秒,请使用reactor.callLater(N, someFunction)

    一旦您从程序中删除 sleep 调用,仅仅因为您停止反应器处理事件而导致不相关超时的问题就会消失。

    【讨论】:

    • reactor.callLater 就目前而言是好的;但是,您如何获得延迟暂停执行几秒钟。如在延迟执行中,我如何获得 time.sleep(20) 行为!
    • 这个问题没有意义。延期不执行。它们是可能尚不可用的结果的 API。
    • 好的,太好了。它是一个用于可能尚不可用的结果的 API。知道了。所以,如果你正在写一个 deferred,并且在 deferred 内你必须暂停几秒钟,这样你才能正确地获得未来的价值。你必须暂停。否则未来的价值将是错误的。你是怎么做到的?
    【解决方案2】:

    对于任何偶然发现此线程的人,绝对不要致电time.sleep(...);但是,可以创建一个除了睡眠之外什么都不做的Deferred...您可以使用它来将延迟组合成一个延迟链:

       def make_delay_deferred(seconds, result=None):
           d = Deferred()
           reactor.callLater(seconds, d.callback, result)
           return d
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多