代码之家  ›  专栏  ›  技术社区  ›  Arpit Solanki

运行时错误:从不调用结果。任务芹菜中的get()

  •  15
  • Arpit Solanki  · 技术社区  · 8 年前

    我用芹菜发送一个任务到远程服务器,并试图得到结果回来。使用不断更新任务状态 update_state

    我正在使用发送任务

    app.send_task('task_name')
    

    所以我试着运行另一个芹菜任务来获得结果。

    @app.task(ignore_result=True)
    def catpure_res(task_id):
        task_obj = AsyncResult(task_id)
        task_obj.get(on_message=on_msg)
    

    但它会导致以下错误。

    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 367, in trace_task
        R = retval = fun(*args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 622, in __protected_call__
        return self.run(*args, **kwargs)
      File "/home/arpit/project/appname/tasks/results.py", line 42, in catpure_res
        task_obj.get(on_message=on_msg)
      File "/usr/local/lib/python2.7/dist-packages/celery/result.py", line 168, in get
        assert_will_not_block()
      File "/usr/local/lib/python2.7/dist-packages/celery/result.py", line 44, in assert_will_not_block
        raise RuntimeError(E_WOULDBLOCK)
    RuntimeError: Never call result.get() within a task!
    See http://docs.celeryq.org/en/latest/userguide/tasks.html#task-synchronous-subtasks
    

    是否有解决此错误的方法。我必须运行守护进程才能获得结果吗?

    2 回复  |  直到 8 年前
        1
  •  19
  •   Arpit Solanki    8 年前

    allow_join_result

    @app.task(ignore_result=True)
    def catpure_res(task_id):
        task_obj = AsyncResult(task_id)
        with allow_join_result():
            task_obj.get(on_message=on_msg)
    

        2
  •  3
  •   ItayB    8 年前

    正如你的标题所解释的那样 get 在任务内是一种不好的做法,可能会导致死锁。 相反,您可以检查任务状态并 只要准备好,就会产生:

    result = catpure_res.AsyncResult(task_id, app=app)
        if result.ready():
            return result.get()
    
        return result.state
    

    您可以将上述代码段包装在一个函数中,并每隔x秒请求一次。

    请注意您的评论:

    • result.state 相反,使用 retry 具有的机制 countdown 直到完成任务 result.state == SUCCESS

    • 你可以加芹菜 beat

    • 请注意,使用如此繁重的任务(持续时间长)也是一种不好的做法。考虑将其分解为一个小任务并使用 canvas 将它们结合起来。

    推荐文章