2012-08-17 124 views
14

我有个任务(确保任务一次只能执行一个),有点像这样:芹菜任务计划

@task() 
def async_work(info): 
    ... 

在任何时候,我可以叫async_work一些信息。出于某种原因,我需要确保一次只运行一个async_work,其他调用请求必须等待。

于是我想出了下面的代码:

is_locked = False  
@task() 
    def async_work(info): 
     while is_locked: 
      pass 
     is_locked = True 
     ... 
     is_locked = False 

但它说,这是无效的访问局部变量... 如何解决呢?

+0

你能发布确切的错误信息吗? – 2012-08-17 09:31:50

回答

21

访问本地变量是无效的,因为您可以有几个芹菜工人运行任务。而这些工作人员甚至可能在不同的主机上。因此,基本上,尽可能多的is_locked变量实例与许多芹菜工人正在运行 您的async_work任务一样。因此,即使你的代码不会引发任何错误,你也不会得到期望的效果。

为了实现您的目标,您需要配置芹菜运行只有一名工人。由于任何工人都可以在任何特定时间处理单个任务,因此您可以获得所需的任务。

编辑:

根据Workers Guide > Concurrency

默认情况下,多用于中 任务执行并发执行,但你也可以使用Eventlet。可以使用--concurrency自变量 来更改进程/线程的工作者数量 ,并且默认为机器上可用的CPU数量。

因此,你需要运行这样的工人:

$ celery worker --concurrency=1 

编辑2:

令人惊讶的还有另一种解决方案,而且它甚至在官方的文档,请参阅Ensuring a task is only executed one at a time文章。

+0

你能更明确地解释吗?如何配置芹菜只运行一个工人? – 2012-08-17 09:59:25

+0

“$芹菜工人 - 并发性= 1”这工作得很好!的确如此。 – 2012-08-17 10:54:29