簡體   English   中英

使用celery在Django中非周期性地重復執行任務

[英]Non-periodic repetition of task in Django using celery

我需要在隨機的時間間隔內運行任務“ CreateNotifications”。 這是我在CELERY設置中嘗試執行的操作。

t = random.randint(45, 85)
## print "time = ", t

## celery app configuration
app.conf.CELERYBEAT_SCHEDULE = {
    # Executes at every 't' interval, where t is random
    'create-notifications': {
        'task': 'apps.notifications.tasks.CreateNotifications',
        'schedule': timedelta(seconds=t),
    },
}

現在的問題是,對於CELERY的這些設置僅執行一次(當我運行命令python manage.py runserver時),因此變量't'以及因此timedelta中的'seconds'值將獲得隨機值,但僅執行一次。

最終,使上述過程成為一個周期性的過程,周期為X秒,當我啟動服務器時,僅隨機選擇X。

另外,我嘗試運行一個任務,並在其中使用了無限循環的while循環,並且有一個隨機延遲,因此celery僅自動檢測到一個任務,而該任務永遠不會結束。 我的目的是通過while循環中的隨機延遲解決的。 像這樣(NOTE->'while'在函數CreateNotifications()內)

@app.task
def CreateNotifications():

while True:

    upper_limit = models.MyUser.objects.all().aggregate(Max('id'))
    lower_limit = models.MyUser.objects.all().aggregate(Min('id'))

    ## select a user to be notified randomly

    to_user = None
    to = 0

    while to_user is None:
        to = random.randint(lower_limit['id__min'], upper_limit['id__max'])
        try:
            to_user = models.MyUser.objects.get(id=to)
        except:
            pass

    ## select a user to be notified from randomly

    frm_user = None
    frm = to

    while frm_user is None:
        while frm == to:
            frm = random.randint(lower_limit['id__min'], upper_limit['id__max'])
        try:
            frm_user = models.MyUser.objects.get(id=frm)
        except:
            pass

    notif_type = ['comment on', 'liked', 'shared']
    notif_media = ['post', 'picture', 'video']

    models.Notification.objects.create(
        notified_user = to_user,
        notifier = frm_user,
        notification_type = random.choice(notif_type),
        notification_media = random.choice(notif_media))

    to_user.new_notification_count += 1
    to_user.save()


    t = random.randint(35, 55)
    print "delay = ", t
    time.sleep(t)

它的工作完全符合我的要求,但是現在有4個不同的工人執行同一任務,但是我只需要一個。

我已嘗試更改位於我virtualenv / bin /目錄中的celeryd文件,如此處所示-> Celery。 減少進程數

因為/ etc / defaults /中沒有celeryd文件,但仍然沒有成功

任何幫助將不勝感激。

您真的不應該在芹菜任務中無休止的循環。 如果您需要專用的流程,則最好自己運行而不是通過Celery。

您可以在以后每次任務運行時重新計划新任務。 類似於以下內容:

@app.task
def create_notifications():
     try:
          #
     finally:
          t = random.randint(45, 85)
          create_notifications.apply_async(countdown=t)

另一個選擇是讓調度程序任務按常規時間表運行,但在不久的將來將通知任務排入隨機時間。 例如,如果調度程序任務每45秒運行一次。

@app.task
def schedule_notifications():
     t = random.randint(0, 40)
     create_notifications.apply_async(countdown=t)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM