Live code reloading은 개발자가 코드 변경에 따른 피드백을 즉각적으로 받을 수 있는 간단하면서도 효과적인 방법입니다. Uvicorn의 경우에는 기본적으로 이 기능을 제공하지만 Celery는 제공하지 않는다는 아쉬움이 있습니다.
따라서 코드 변경시 수동으로 다시 기동해야 하므로 개발 환경에 있어 어려움중에 하나입니다.
이번에는 Celery woker의 auto-reload 문제를 해결하여 코드 변경시 Celery worker가 다시 시작되도록 하는 방법을 보겠습니다.
--reload
플래그로 Uvicorn을 기동하였으므로 파일 감시 및 code reload에 사용되는 도구인 watchgod가 사용되게 됩니다.
web_1 | INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
web_1 | INFO: Started reloader process [8] using watchgod
web_1 | INFO: Started server process [10]
web_1 | INFO: Waiting for application startup.
web_1 | INFO: Application startup complete.
Celery Worker를 리로드하는 데 watchgod를 사용 할 수 있습니다.
먼저 requirements.txt 파일 하단에 아래 라이브러리를 추가 할게요.
watchgod==0.7
main.py 파일을 수정합니다.
from project import create_app
app = create_app()
celery = app.celery_app
def celery_worker():
from watchgod import run_process
import subprocess
def run_worker():
subprocess.call(
["celery", "-A", "main.celery", "worker", "--loglevel=info"]
)
run_process("./project", run_worker)
if __name__ == "__main__":
celery_worker()
project디렉토리 아래 파이썬 파일을 recursive하게 모니터링하게 하기 위해서 celery_worker함수 호출 이후 run_proces함수가 호출되도록 callback 함수를 만들었습니다. 코드 변경시 함수 호출이 발생합니다.
__name__ == 'main': 코드 추가에 따라 python main.py
명령어로 기존 길었던 명령어를 대체 할 수 있습니다.
compose/local/fastapi/celery/worker/start
파일을 수정합니다.
#!/bin/bash
set -o errexit
set -o nounset
# celery -A main.celery worker --loglevel=info
python main.py
이미지를 다시 빌드하고 재기동 하겠습니다.
$ docker-compose up -d --build
auto-reload가 잘 적용 되었는지 확인해 봅니다.
$ docker-compose logs -f
project/users/tasks.py 파일의 divide task의 코드를 살짝 변경하고 저장합니다.
그럼 워커가 자동으로 재시작 하는 모습이 터미널을 통해 확인 할 수 있습니다.