Python Celery:状态更改后更新Django模型

时间:2018-10-13 12:17:16

标签: python django redis celery

通过讨论此问题,我设法找到了2个类似的主题,但不幸的是,我无法从中获得最佳解决方案:

  1. Update Django Model Field Based On Celery Task Status
  2. Update Django Model Field Based On Celery Task Status

我使用Django&Celery(+ redis作为消息代理),并且当celery任务状态发生更改(从挂起->成功,挂起->失败)等时,我想更新Django模型。

我的代码:

import time

from celery import shared_task

@shared_task(name="run_simulation")
def run_simulation(simulation_id: str):
    t1_start = time.perf_counter()
    doSomeWork() # we may change this to sleep for instance
    t1_end = time.perf_counter()
    return{'process_time': t1_end - t1_start}

以及我从中调用任务的特定视图:

def run_simulation(request):
    form = SimulationForm(request.POST)
    if form.is_valid():
        new_simulation = form.save()
        new_simulation.save()
        task_id = tasks.run_simulation.delay(new_simulation.id)

问题是,更改任务状态后,更新Simulation的Django模型状态的首选方法是什么?

在文档中,我发现使用方法on_failureon_success等的处理程序。http://docs.celeryproject.org/en/latest/userguide/tasks.html#handlers

1 个答案:

答案 0 :(得分:0)

我认为没有一种首选的方法来执行这样的操作,因为它取决于您的项目。 您可以使用监视任务,例如发送的链接。为任务指定任务ID,然后重新安排任务,直到受监视的任务处于“完成”状态。

from celery import AsyncResult

@app.task(bind=True)
def monitor_task(self, t_id):
    """Monitor a task"""
    res = AsyncResult(t_id, backend=self.backend, app=self.app)
    if res.ready():
        raise self.retry(
            countdown=10,
            exc=Exception("Main task not done yet.")
        )

您还可以创建事件接收器并检查任务的状态,然后将其保存在数据库中。 http://docs.celeryproject.org/en/latest/userguide/monitoring.html#real-time-processing

现在,如果您仅对成功和失败状态感兴趣,则可以创建成功和失败回调,并关心将成功或失败状态保存在该数据库中。

tasks.run_simulation.apply_async(
    (sim_id,),
    link=tasks.success_handler.s(),
    link_error=tasks.error_handler()
)

http://docs.celeryproject.org/en/latest/userguide/calling.html#linking-callbacks-errbacks