我正在使用带有2个任务的Celery 3.1.x.当Celery通过celeryd_after_setup信号启动时,第一个任务(TaskOne)被排队:
@celeryd_after_setup.connect
def celeryd_after_setup(*args, **kwargs):
TaskOne().apply_async(countdown=5)
运行TaskOne时,会进行一些计算,然后将TaskTwo排入队列。想象一下以下工作流程:
所以队列中有2个TaskTwo。这对我的工作流程来说是一个问题,因为我只需要队列中有一个TaskTwo,并避免第二个被排队。
我的问题:我怎样才能做到这一点?
使用celery.app.control.Inspect.scheduled()
(Docs)我可以获得一个列表,列出哪些任务已安排,隐藏在列表和词组的组合中。这可能是一种方式,但通过这样的结果感觉不对。还有更好的办法吗?
答案 0 :(得分:0)
易于实现的解决方案是将--purge开关添加到您的worker命令。它将清除队列,并且工作人员从没有预定作业开始。
但要注意:这是一种全球性,无法恢复的工作。当您还有其他预定的工作时,这不是您的解决方案。
答案 1 :(得分:0)
在考虑了几个选项后,我选择使用app.control.inspect。 它不是一个非常漂亮的解决方案,但它有效:
# fetch all scheduled tasks
scheduled_tasks = inspect().scheduled()
# iterate the scheduled task values, see http://docs.celeryproject.org/en/latest/userguide/workers.html?highlight=revoke#dump-of-scheduled-eta-tasks
for task_values in iter(scheduled_tasks.values()):
# task_values is a list of dicts
for task in task_values:
if task['request']['name'] == '{}.{}'.format(TaskTwo.__module__, TaskTwo.__name__):
logger.info('TaskTwo is already scheduled, skipping additional run')
return