Developing and testing Celery background tasks¶
How Celery is configured¶
Celery is configured according to the Celery first steps with Django guide. The app is in devilry.project.common.celery, and it is imported as celery_app in devilry/project/common/__init__.py.
For production, we leave the configuration up to sysadmins.
For development, we default to running Celery in eager mode, but we have commented out settings in devilry.project.develop.develop for “real” Celery testing. Eager mode means that all celery tasks runs in blocking mode in the current thread, so celery tasks runs just like any other function.
For unit tests, we run Celery in eager mode (configured in devilry.project.develop.test).
Testing with non-eager Celery¶
Install Redis¶
See https://redis.io/. On Mac OSX, you can install Redis using Homebrew:
$ brew install redis
Start the Redis server¶
To start the redis server, run:
$ redis-server
To stop the server, run:
$ redis-server stop
To stop the server on OSX, run:
$ redis-cli shutdown
Start the Celery worker¶
Run:
$ celery -A devilry.project.common worker -l debug
It should print some info about the config, the tasks that it detects in Devilry, and stop for input with the following message: celery@<your machine name> is ready.
Try one of the test-tasks¶
Open the Django shell, and run one the test-tasks (while Redis and the Celery worker are both running):
$ python manage.py shell
>>> from devilry.project.develop.tasks import add
>>> result = add.delay(10, 20)
>>> result.wait()
30
If this works, Celery is configured correctly, and you should be able to see the job in the terminal where the worker is running.
Things to remember¶
(when running Celery tasks through the Celery worker)
- The output (stdout and stderr) goes to the Celery worker, not to runserver.
- You can get more verbose output from the worker with worker -l debug.
Testing email sending with django-celery-email¶
Uncomment the following lines in devilry.project.develop.settings.develop:
# INSTALLED_APPS += ['djcelery_email']
# EMAIL_BACKEND = 'djcelery_email.backends.CeleryEmailBackend'
# CELERY_EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
And run the following in the Django shell:
>>> from django.contrib.auth import get_user_model
>>> from devilry.utils.devilry_email import send_message
>>> send_message('Testsubject', 'Testmessage', get_user_model().objects.get(username='april'))