15.3.20. crate_anon.crateweb.consent.tasks¶
Copyright (C) 2015-2018 Rudolf Cardinal (rudolf@pobox.com).
This file is part of CRATE.
CRATE is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
CRATE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with CRATE. If not, see <http://www.gnu.org/licenses/>.
See also crate_anon.crateweb.consent.celery
, which defines the app
If you get a “received unregistered task” error:
- Restart the Celery worker. That may fix it.
- If that fails, consider: SPECIFY ABSOLUTE NAMES FOR TASKS. e.g. with @shared_task(name=”myfuncname”) Possible otherwise that if this module is imported in different ways (e.g. absolute, relative), you’ll get a “Received unregistered task” error. http://docs.celeryq.org/en/latest/userguide/tasks.html#task-names
Acknowledgement/not doing things more than once:
- http://docs.celeryproject.org/en/latest/userguide/tasks.html
- default is to acknowledge on receipt of request, not after task completion; that prevents things from happening more than once. If you can guarantee your function is idempotent, you can acknowledge after completion.
- http://docs.celeryproject.org/en/latest/faq.html#faq-acks-late-vs-retry
- We’ll stick with the default (slightly less reliable but won’t be run more than once).
Circular imports:
http://stackoverflow.com/questions/17313532/django-import-loop-between-celery-tasks-and-my-models # noqa
The potential circularity is:
- At launch, Celery must import tasks, which could want to import models.
- At launch, Django loads models, which may use tasks.
Simplest solution is to keep tasks very simple (as below) and use delayed imports here.
Race condition:
Django:
- existing object
- amend with form
- save()
- call function.delay(obj.id)
Object is received by Celery in the state before save() at step 3.
http://celery.readthedocs.org/en/latest/userguide/tasks.html#database-transactions # noqa
SOLUTION: https://docs.djangoproject.com/en/dev/topics/db/transactions/#django.db.transaction.on_commit # noqa
from django.db import transaction transaction.on_commit(lambda: blah.delay(blah))
Requires Django 1.9. As of 2015-11-21, that means 1.9rc1