【问题标题】:Wait for the result of an external webservice inside a task在任务中等待外部网络服务的结果
【发布时间】:2011-09-22 12:16:48
【问题描述】:

我需要编写一堆任务,其中每个任务都需要查询外部 Web 服务。 Web 服务始终以 202 ACCEPTED 状态回复,并在 Location 标头中指向可以轮询结果的 URI。此 Web 服务交付结果所需的时间可能从 2 秒到 1 分钟不等。我想知道编写芹菜任务的最佳方法是什么。现在我发送请求并开始一个while循环,直到我成功轮询结果,例如:

while True:
    result = poll_webservice()
    if result:
        break
    else:
        time.sleep(5)

[ continue with the rest of the task ]

虽然这确实有效,但对我来说似乎很粗糙,而且我阻止 celery worker 直到结果被轮询。有没有更好的方法?

【问题讨论】:

  • 如果您正在调用一个真正的 web 服务,脚本应该只在它得到答案时继续 - 参见Dive into Python SOAP page 的一些例子
  • @JMax,有docs.picloud.com/rest.html之类的可能,所以他不能那样做。
  • @hymloth: 感谢您指出这个网址

标签: python celery


【解决方案1】:

你肯定是在扼杀你的资源。只需查询您的外部 Web 服务并保存要轮询的 URI(使用缓存或数据库)。然后您可以拥有一个收集结果的 periodic task,如果准备好...

【讨论】:

    【解决方案2】:

    我正在考虑一项 celery 任务,该任务会轮询 202 响应提供的位置。如果完成,则处理它,否则它会在一段时间后重新排队自己(或自己的副本)。

    对于奖励积分,如果您有很多此类任务,则可以在每次响应未准备好时增加投票之间的时间。

    【讨论】:

      【解决方案3】:

      使用task.retry 怎么样?

      @task(max_retries=100)
      def poll_webservice_task(url):
          result = poll_webservice(url)
          if result:
             return result
          poll_webservice_task.retry(countdown=5)
      

      【讨论】:

      • 还要记得设置一个合适的max_retries: @task(max_retries=None) 没有限制。
      • 这就是要走的路。我不知道 apply_async 的 countdowneta 参数。通过这些论点和子任务的使用,我认为我可以很好地解决问题。感谢您的意见。
      猜你喜欢
      • 2016-06-15
      • 2023-03-08
      • 1970-01-01
      • 2017-06-02
      • 1970-01-01
      • 2020-09-27
      • 1970-01-01
      • 2019-02-24
      • 1970-01-01
      相关资源
      最近更新 更多