График работы с сельдереем (Celery, Django и RabbitMQ) - PullRequest
10 голосов
/ 19 марта 2011

Я хочу иметь задачу, которая будет выполняться каждые 5 минут, но она будет ждать окончания последнего выполнения, а затем начнет считать эти 5 минут. (Таким образом, я также могу быть уверен, что выполняется только одна задача) Самый простой способ, который я нашел, это запустить оболочку django для управления manage.py и запустить это:

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

но для каждой задачи, которую я хочу выполнить таким образом, мне нужно запустить свою собственную оболочку, есть ли простой способ сделать это? Может быть, какой-нибудь король обычай от Джанго планировщик сельдерея?

Ответы [ 6 ]

17 голосов
/ 12 июля 2013

Ух, как удивительно, что никто не понимает вопрос этого человека.Они спрашивают не о том, чтобы запускать задачи периодически, а о том, как обеспечить, чтобы Celery не запускал два экземпляра одной и той же задачи одновременно.Я не думаю, что есть способ сделать это напрямую с Celery, но вы можете сделать так, чтобы одна из задач получила блокировку сразу же после ее запуска, а в случае неудачи - повторить попытку через несколько секунд (используя повторную попытку).,Задача снимет блокировку прямо перед возвратом;Вы можете сделать автоматическое истечение срока действия блокировки через несколько минут, если она выйдет из строя или выйдет из строя.

Для блокировки вы, вероятно, можете просто использовать свою базу данных или что-то вроде Redis.

16 голосов
/ 27 апреля 2011

Возможно, вас заинтересует этот более простой метод, который не требует никаких изменений в конфетах из сельдерея.

@celery.decorators.periodic_task(run_every=datetime.timedelta(minutes=5))
def my_task():
    # Insert fun-stuff here
12 голосов
/ 19 марта 2011

Все, что вам нужно, это указать в задаче celery 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, помните, что вы также можете использовать thj django db в качестве планировщика для периодических задач, таким образом вы можете легко добавлять через панель администратора django-celery новые периодические задачи. Для этого вам нужно установить планировщик сельдерея в файле settings.py следующим образом

CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
4 голосов
/ 19 марта 2011

Чтобы расширить пост @ MauroRocco, от http://docs.celeryproject.org/en/v2.2.4/userguide/periodic-tasks.html

Использование временной шкалы для расписания означает, что задание будет выполнено через 30 секунд после запуска сельдерея, а затем каждые 30 секунд после последнего запуска. Также существует расписание, подобное crontab, см. Раздел о расписаниях Crontab.

Так что это действительно достигнет желаемой цели.

2 голосов
/ 05 мая 2013

Из-за устаревания celery.decorators вы можете использовать декоратор period_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
0 голосов
/ 15 февраля 2016

Добавьте эту задачу в отдельную очередь, а затем используйте отдельного работника для этой очереди с параметром параллелизма, установленным в 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...