2011-12-15 89 views
1

我想用芹菜來管理任務。 我現在遇到的問題是,我有很多次要任務(電子郵件,跨服務器帖子等) 和時間消耗任務,如文件上傳。芹菜,一個再見一個隊列和並行許多在隊列中

有沒有什麼方法來指定上傳總是會一個接一個的。只有一項任務能夠及時執行,而其他工作人員則會在其他隊列中工作?

回答

0

序列化任務執行的有效方法是使用互斥(互斥)。

Python的threading模塊有a Lock object可以是used to this effect

# ... 
module_lock = threading.Lock() # or make this an attribute in an object with sufficiently-large scope 
# ... 
def do_interesting_task(): 
    with module_lock.acquire(): 
     interesting_task() 

「放棄所有希望,你們誰在此處輸入」。

互斥鎖和信號量是強大的工具,但不明智地使用它們會產生僵局,偶爾會吃掉你的午餐。

+3

我不認爲這會同時工作的工人調節至2/3 /任何其他數量的並行限制。每個工人都會有全新的module_lock,或者我錯了?無論如何,現在張貼我解決這個問題的方式。會很高興聽到它的意見,也許它有一些嚴重的缺乏,我沒有看到第一種方法 – Tigra 2011-12-16 11:26:11

0

同時我已經實施了這樣的解決方案,效果很好。 但是,我不太確定,max_retries = None表示將有無限次的重試次數。 該解決方案適用於redis,但可以在支持atomicaly增量操作的任何其他引擎上工作。

@task(max_retries=None,default_retry_delay=3) 
def sleepTask(): 
    if r.incr('sleep_working')>1: 
     r.incr('sleep_working',-1) 
     sleepTask.retry() 
    else: 
     try: 
      r.expire('sleep_working',3600) 
      sleep(30) 
     finally: 
      r.incr('sleep_working',-1) 
     return True 

這裏的關鍵是,增量是原子,所以它永遠不會發生,這兩個客戶端接收計數器== 1。

也到期是非常重要的,任何事情都可能發生,我們將永遠得到我們的計數器> 1,所以到期確認,無論如何,經過特定的時間計數器將被丟棄。這個值可以根據需要進行調整。我的大文件上傳,所以3600聽起來不錯。

我認爲這是一個很好的起點,通過接收redis_key和expire_time值來創建自定義Task對象,它將自動執行所有這些操作。我會更新這個帖子,如果我會做這樣的任務。

作爲獎勵,這種解決方案也可以容易地通過改變> 1至>任何數量