2011-03-19 481 views
10

我想有一個任務,每5分鐘執行一次,但它會等待最後一次執行完成,然後開始計算這5分鐘。 (這樣我也可以肯定的是,只有一個任務運行),我發現最簡單的方法是運行Django應用程序manage.py shell並運行此:芹菜任務計劃(芹菜,Django和RabbitMQ)

while True: 
    result = task.delay() 
    result.wait() 
    sleep(5) 

但我要執行的每個任務這樣我必須運行它自己的shell,有沒有簡單的方法來做到這一點?可能是一些國王定製ot Django芹菜調度?

回答

12

所有你需要的是指定你想定期運行的芹菜conf conf女巫的任務和間隔。

例:運行tasks.add任務每30秒

from datetime import timedelta 

CELERYBEAT_SCHEDULE = { 
    "runs-every-30-seconds": { 
     "task": "tasks.add", 
     "schedule": timedelta(seconds=30), 
     "args": (16, 16) 
    }, 
} 

請記住,你必須與-B選項

manage celeryd -B 

您也可以使用crontab運行節拍模式芹菜樣式而不是時間間隔,結帳:

http://ask.github.com/celery/userguide/periodic-tasks.html

如果您使用的是django-celery,請記住您也可以使用tha django db作爲日程安排任務,這樣您可以輕鬆添加槽django-celery管理面板中的新週期性任務。 爲了做到這一點,你需要設置settings.py中的celerybeat調度這樣

CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler" 
+2

問題在於它不會等待任務完成,但會在時間(每30秒)時發送另一個任務。或者可能是我錯了? – 2011-03-19 10:58:39

+0

感謝您的建議,但我想我還想要別的東西 - 我想創建一個工作,發送它執行,並在上一個執行完成時創建另一個工作。直到我知道上一個完成之前,我不想創造就業機會。我希望任務具有同步(而非異步)行爲 – 2011-03-20 10:01:59

+0

全局目標是運行一個任務,我無法分辨需要花費多少時間並完成任務,等待一段時間後再重新開始。另外,我必須確定它不會被不同的工作線程同時執行2次或更多次,並且我不必編寫自己的程序代碼來執行此操作。 – 2011-03-21 07:24:11

4

爲了擴大對@ MauroRocco的帖子,從http://docs.celeryproject.org/en/v2.2.4/userguide/periodic-tasks.html

使用日程表的timedelta意味着任務會在celerybeat開始後30秒執行,然後在最後一次運行後每30秒執行一次。類似crontab的時間表也存在,請參閱關於Crontab時間表的部分。

因此,這將確實達到你想要的目標。

+0

對不起,關於這個問題,但如果任務需要20秒才能完成,它將在0:30(1-st)運行,在0:50完成,然後以1:20開始(這是我真正想要的) – 2011-03-19 19:50:16

+2

如果您希望任務每30秒獨立於持續時間運行,而不是必須使用crontab進度表,但請記住此任務已添加到芹菜隊列中,並且如果有其他任務正在執行/正在排隊,則您無法確定你的任務在給定的時間開始。 – 2011-03-19 20:14:50

16

您可能會對這種簡單的方法感興趣,而無需更改芹菜conf。

@celery.decorators.periodic_task(run_every=datetime.timedelta(minutes=5)) 
def my_task(): 
    # Insert fun-stuff here 
+0

我得到一個錯誤「芹菜」對象沒有屬性「裝飾者」。對此有何想法?我在我的任務上面寫了@ celery.decorators.periodic_task(run_every = datetime.timedelta(分鐘= 5))。 – Simer 2017-03-16 11:34:29

+0

最新版本的芹菜沒有這個裝飾。您必須在此處使用說明:http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html – 2017-03-17 17:12:14

2

由於棄用celery.decorators的,你可以使用periodic_task裝飾這樣的:

from celery.task.base import periodic_task 
from django.utils.timezone import timedelta 

@periodic_task(run_every=timedelta(seconds=5)) 
def my_background_process(): 
    # insert code 
17

哇這是驚人的怎麼沒人理解這個人的問題。他們不是在詢問有關定期運行的任務,而是如何確保Celery不會同時運行同一任務的兩個實例。我不認爲有一種方法可以直接與Celery做到這一點,但是你可以做的是讓其中一項任務在開始時獲得鎖定權限,如果失敗,幾秒鐘後重試(使用重試) 。任務將在返回之前釋放鎖定權限;您可以在幾分鐘後使鎖自動失效,如果它崩潰或超時。

對於鎖,你可以使用你的數據庫或類似Redis的東西。

+0

+1。解決唯一實例問題的唯一人!有關如何使用django數據庫實現鎖的詳細信息可以在這裏找到:http://stackoverflow.com/questions/4095940/running-unique-tasks-with-celery – jcdude 2014-05-13 16:05:50

0

將該任務添加到單獨的隊列中,然後使用該併發選項設置爲1的該隊列的單獨工作人員。