2012-08-17 138 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