what is it?
how celery works under the hood when paired with django
django ORM access in celery
when celery initialises a new task, django.setup is called
class DjangoWorkerFixup:
_db_recycles = 0
def __init__(self, app: "Celery") -> None:
self.app = app
self.db_reuse_max = self.app.conf.get('CELERY_DB_REUSE_MAX', None)
self._db = cast("DjangoDBModule", import_module('django.db'))
self._cache = import_module('django.core.cache')
self._settings = symbol_by_name('django.conf:settings')
self.interface_errors = (
symbol_by_name('django.db.utils.InterfaceError'),
)
self.DatabaseError = symbol_by_name('django.db:DatabaseError')
def django_setup(self) -> None:
import django
django.setup()
def validate_models(self) -> None:
from django.core.checks import run_checks
self.django_setup()
if not os.environ.get('CELERY_SKIP_CHECKS'):
run_checks()django.setup is used to create a standalone django app, which provides access to the django ORM and application registry inside each worker
logging configuration
by default, Celery “hijacks” and modifies the root logger
def setup_logging_subsystem(....)
root = logging.getLogger()
if self.app.conf.worker_hijack_root_logger:
root.handlers = []
get_logger('celery').handlers = []
get_logger('celery.task').handlers = []
get_logger('celery.redirected').handlers = []
# Configure root logger
self._configure_logger(
root, logfile, loglevel, format, colorize, **kwargs
)
# Configure the multiprocessing logger
self._configure_logger(
get_multiprocessing_logger(),
logfile, loglevel if MP_LOG else logging.ERROR,
format, colorize, **kwargs
)worker_hijack_root_logger defaults to True, which means celery clears the root handlers and resets the root log level