Основи Python и Django. / Djangoc використанням черги завдань Celery. / Використовуємо Celery з Django.
Для роботи Celery нам знадобиться база даних Redis.
Встановлення Redis.
Створимо новий контейнер у файлі docker-compose.yaml.
Це дозволяє не гальмувати основний процес будь-якими довгоживучими завданнями та налагоджувати їх.
Для роботи Celery нам знадобиться база даних Redis.
Встановлення Redis.
Створимо новий контейнер у файлі docker-compose.yaml.
redis-server:
image: "redis:alpine"
Запуск контейнера.
docker-compose run redis-server
Увімкнемо його запуск у tmux
split-window -h \; \
...
select-pane -t 2 \;
send-keys 'docker-compose run redis-server' C-m \; \
Установка Celery.
pip install celery redis
Далі нам необхідно створити програму celery у новому файлі celery_app.py поряд з settings.py.
from celery import Celery
from django.conf import settings
from celery.schedules import crontab
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'prj.settings')
app = Celery('prj')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
Додати імпорт у init.py
from .celery_app import app as celery_app
У settings.py встановити Redis як брокер повідомлень
REDIS_HOST = os.getenv('SQL_HOST', 'localhost')
REDIS_PORT = os.getenv('SQL_PORT', '6379')
CELERY_BROKER_URL = 'redis://' + REDIS_HOST + ':' + str(REDIS_PORT)
Створимо новий контейнер під чергу завдань celery.
celery-tasks:
build: .
restart: always
working_dir: /app
command: celery -A prj worker -l info
volumes:
- ./prj:/app
depends_on:
- redis-server
env_file:
- ./.env.dev
container_name: celery-tasks
Планувальник.
Для того, щоб запускати завдання за заданим розкладом, нам знадобиться запускати окремий процес, який буде класти в чергу завдання за заданим інтервалом часу.
Цей процес називається cellery-beat.
Запускається командою.
celery -A prj beat
Створимо завдання, що виводить поточний час на екран у файлі celery.py
from datetime import datetime
@app.task(bind=True)
def timer_task(self):
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
print(f'Time is: {current_time}')
bind=True - дозволяє звертатися до екземпляра завдання всередині її самої наприклад так self.retry(countdown=5)
Далі створимо планувальник і запустимо завдання з інтервалом 1 хв.
app.conf.beat_schedule = {
'timer-task': {
'task': 'prj.celery.timer_task',
'schedule': crontab(minute='*/1'),
}
}
Посилання на документацію за інтервалами
Створимо окремий контейнер докер під celery-beat.
celery-beat:
build: .
restart: always
working_dir: /app
command: celery -A prj beat
volumes:
- ./prj:/app
depends_on:
- redis-server
env_file:
- ./.env.dev
container_name: celery-beat
Файл для запуску всіх процесів в окремих вікнах tmux.
#!/bin/bash
command -v tmux >/dev/null 2>&1 || { echo >&2 "I require tmux but it's not installed. Aborting."; exit 1; }
tmux new-session \; \
split-window -v \; \
split-window -h \; \
select-pane -t 0 \; \
split-window -h \; \
split-window -h \; \
send-keys 'docker-compose run db' C-m \; \
select-pane -t 4 \; \
send-keys 'docker-compose run django' C-m \; \
select-pane -t 3 \; \
send-keys 'docker-compose run redis-server' C-m \; \
select-pane -t 0 \; \
send-keys 'docker-compose run celery-tasks' C-m \; \
select-pane -t 1 \; \
send-keys 'docker-compose run celery-beat' C-m \; \
Результат.