• en
  • Language: ru
  • Documentation version: 1.1.x

Фоновые задачи сельдерея

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

Celery - это мощная очередь задач, которую можно использовать как для простых фоновых задач, так и для сложных многоэтапных программ и расписаний. Это руководство покажет вам, как настроить Celery с помощью Flask, но предполагает, что вы уже прочитали руководство First Steps with Celery в документации по Celery.

Установите

Celery - это отдельный пакет Python. Установите его из PyPI с помощью pip:

$ pip install celery

Настроить

Первое, что вам нужно, это экземпляр Celery, который называется приложением celery. Он служит той же цели, что и объект Flask во Flask, только для Celery. Поскольку этот экземпляр используется как точка входа для всего, что вы хотите делать в Celery, например, создавать задачи и управлять рабочими, другие модули должны иметь возможность импортировать его.

Например, вы можете поместить это в модуль tasks. Хотя вы можете использовать Celery без какой-либо переконфигурации с Flask, он становится немного приятнее, если подклассифицировать задачи и добавить поддержку контекстов приложений Flask и связать его с конфигурацией Flask.

Это все, что необходимо для правильной интеграции Celery с Flask:

from celery import Celery

def make_celery(app):
    celery = Celery(
        app.import_name,
        backend=app.config['CELERY_RESULT_BACKEND'],
        broker=app.config['CELERY_BROKER_URL']
    )
    celery.conf.update(app.config)

    class ContextTask(celery.Task):
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return self.run(*args, **kwargs)

    celery.Task = ContextTask
    return celery

Функция создает новый объект Celery, конфигурирует его с брокером из конфигурации приложения, обновляет остальную часть конфигурации Celery из конфигурации Flask, а затем создает подкласс задачи, который оборачивает выполнение задачи в контекст приложения.

Пример задания

Давайте напишем задачу, которая складывает два числа и возвращает результат. Мы настроим брокер и бэкенд Celery на использование Redis, создадим приложение celery, используя фактор из примера выше, а затем используем его для определения задачи.

from flask import Flask

flask_app = Flask(__name__)
flask_app.config.update(
    CELERY_BROKER_URL='redis://localhost:6379',
    CELERY_RESULT_BACKEND='redis://localhost:6379'
)
celery = make_celery(flask_app)

@celery.task()
def add_together(a, b):
    return a + b

Теперь эта задача может быть вызвана в фоновом режиме:

result = add_together.delay(23, 42)
result.wait()  # 65

Запустить рабочего

Если вы вскочили и уже выполнили приведенный выше код, вы будете разочарованы, узнав, что .wait() на самом деле никогда не вернется. Это потому, что вам также необходимо запустить Celery worker для получения и выполнения задания.

$ celery -A your_application.celery worker

Строка your_application должна указывать на пакет или модуль вашего приложения, который создает объект celery.

Теперь, когда рабочий запущен, wait вернет результат после завершения задания.