Celery限制队列中特定任务的数量

时间:2015-05-27 19:57:11

标签: python queue task celery worker

我正在使用带有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排入队列。想象一下以下工作流程:

  • 我开始芹菜,因此信号被触发并且TaskOne被排队
  • 倒计时之后
  • (5)TaskTwo入队
  • 然后我停止了芹菜(TaskTwo仍然在队列中)
  • 之后我重新开始芹菜
  • 再次运行工作流并再次将TaskTwo排队

所以队列中有2个TaskTwo。这对我的工作流程来说是一个问题,因为我只需要队列中有一个TaskTwo,并避免第二个被排队。

我的问题:我怎样才能做到这一点?

使用celery.app.control.Inspect.scheduled()Docs)我可以获得一个列表,列出哪些任务已安排,隐藏在列表和词组的组合中。这可能是一种方式,但通过这样的结果感觉不对。还有更好的办法吗?

2 个答案:

答案 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