해당 글은 Celery 4.4.1 documentation을 읽으면서 혼자 정리한 글입니다.

원문은 [First steps with Django — Celery 4.4.1 documentation](https://docs.celeryproject.org/en/stable/django/first-steps-with-django.html)

불러오는 중입니다...

여기에 있어요!

 

django에서 샐러리 활용하기

먼저 celery를 django prodjct에서 쓸려면 Celery library를 정의해줘야 한다.

일반적으로 모델링을 아래와 같이 했다고 가정한다.

- proj/
  - manage.py
  - proj/
    - __init__.py
    - settings.py
    - urls.py

이럴 경우 proj/proj/celery.py 라는 파일을 새로 만들고 여기에 celery instance를 정의해주는 것을 추천한다.

proj/proj/celery.py

from __future__ import absolute_import, unicode_literals

import os

from celery import Celery

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')

app = Celery('proj')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

해당 파일에 이렇게 작성을 해주고 하나씩 알아보자. 아 이것을 알아보기 전에 먼저 proj/proj/__init__.py module을 작성해줘야 한다. init.py를 작성해주면 이것은 django가 시작했을 때, app을 load해주고, @shared_task decorator를 사용가능하게 되는 것을 보장한다.

proj/proj/init.py

from __future__ import absolute_import, unicode_literals

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app

__all__ = ('celery_app',)

이제 celery.py에 있는 것을 하나씩 보자

from __future__ import absolute_import

이것은 celery.py module이 import 될 때 다른 library와 충돌되지 않도록 해준다.

그 이후에 DJANGO_SETTINGS_MODULE의 환경 변수를 설정해준다.

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')

이 줄이 꼭 필요한 것은 아닌데, 이것을 해주면 항상 설정 모듈이 셀러리 프로그램으로 전달하지 않아도 된다.

app = Celery('proj')

이것은 우리의 libary instance를 이야기 해주는데, 많은 인스턴스를 가질 수 있지만 django를 사용할 때는 이유가 없다.

=> 이해가 안되네??

이제 django setting module을 샐러리 구성에 더해줘야하는데, 이것이 의미하는 것은 너는 복수의 구성 파일을 가질 필요가 없고, 대신에 django setting에서 celery 구성을 바로 할 수 있다. 하지만 너가 원하면 분리할 수도 있다.

app.config_from_object('django.conf:settings', namespace='CELERY')

위에 namespace를 설정해준 것은 celery 구성 옵션들이 모두 앞에 CELERY_가 붙게 되는 것을 의미한다. 예를 들면 broker_url 을 setting하면 이게 CELERY_BROKER_URL로 표시될 것이다. 이것은 worker setting에서도 적용되고, worker_concurrency가 CELERY_WORKER_CONCURRENCY로 표시 될 것이다.

그리고 일반적인 사항으로 재사용 가능한 앱은 모두 tasks.py에 빼서 정의하는 것이다. 그리고 celery에서는 이것은 자동적으로 찾아주는 모듈을 가지고 있다. => tasks.py에 celery tasks에서 반복적으로 재사용할 앱을 정의하라

app.autodiscover_tasks()

위의 줄을 추가해주면 celery가 자동적으로 tasks를 찾는데, 우리가 설치되어 있는 앱에서 찾는다. 

- app1/
    - tasks.py
    - models.py
- app2/
    - tasks.py
    - models.py

 위와 같은 형태라면 celery에서 import 해주지 않아도, 알아서 tasks를 celery가 찾는다.

Using thr @shared_task decorator

재사용 가능한 app은 단지 한 프로젝트에 국한 되지 않을 것이고, 그래서 앱 instance를 다이렉트로 import 해줄 수가 없다. 

하지만 @shared_task 데코레이터는 앱 인스턴스에 국한되지 않고 tasks를 생성해준다.

예를 들어보면 아래와 같다.

from __future__ import absolute_import, unicode_literals

from celery import shared_task
from demoapp.models import Widget


@shared_task
def add(x, y):
    return x + y


@shared_task
def mul(x, y):
    return x * y


@shared_task
def xsum(numbers):
    return sum(numbers)


@shared_task
def count_widgets():
    return Widget.objects.count()


@shared_task
def rename_widget(widget_id, name):
    w = Widget.objects.get(id=widget_id)
    w.name = name
    w.save()

 

# 추가 

작업 모듈을 가지고 오는데 일관성이 있어야 한다.

예를 들어 INSTALLED_APPS에 project.app가 있는 경우 project.app에서 작업을 가져와야 한다. 그렇지 않으면 작업 이름이 달라지게 된다.

+ Recent posts