工人不运行时执行芹菜任务

时间:2020-06-17 20:46:26

标签: django celery django-celery celery-task

我希望即使没有芹菜工人也能执行芹菜任务。该芹菜任务应该像正常功能一样工作,并且无论如何都要执行。

1 个答案:

答案 0 :(得分:1)

有两种方法可以实现此目的。推荐的方法使用broadcast控制命令明确地向工作人员查询已注册任务的列表:

app = Celery(broker='amqp://')

reply = app.control.broadcast('registered', reply=True)
tasks = set(t for n in reply for w in n.values() for t in w)

if 'my_task_name' in tasks:
    # there is an online worker that can handle the task
    # => use async mode
    app.send_task('my_task_name', args=(...), kwargs={...}, ...)
    # or use my_task.apply_async(...)
else:
    # there is no online worker for the task
    # => call the function directly
    my_task(...)

或者,您可以尝试将任务直接发送给代理,并在短时间后检查结果。如果在那之后任务仍然有PENDING的结果,则大概没有工作人员可以处理该任务。在这种情况下,您可以将任务作为普通函数调用:

app = Celery(broker='amqp://', backend='rpc://')

result = app.send_task('my_task_name', args=(...), kwargs={...}, ..., expiration=5)
time.sleep(5)
if result.state == 'PENDING':
    # presumably the task didn't start because there hasn't been any worker
    my_task(...)

但是,第二种方法必须谨慎。任务暂挂的其他原因可能是其他原因(例如,它们很忙并且已预取最大任务数)。此外,此示例还假设您的代理支持AMQP到期(例如RabbitMQ),并且您不会忽略任务结果。

相关问题