|
@@ -1,21 +1,43 @@
|
|
|
import os
|
|
|
+import importlib
|
|
|
|
|
|
from django.conf import settings
|
|
|
from django.core.management import setup_environ
|
|
|
|
|
|
+from carrot.utils import rpartition
|
|
|
from celery.loaders.default import Loader as DefaultLoader
|
|
|
from celery.loaders.djangoapp import Loader as DjangoLoader
|
|
|
|
|
|
-"""
|
|
|
-.. class:: Loader
|
|
|
+LOADER_ALIASES = {"django": "celery.loaders.djangoapp",
|
|
|
+ "default": "celery.loaders.default"}
|
|
|
+LOADER_CLASS_NAME = "Loader"
|
|
|
+_loader_cache = {}
|
|
|
|
|
|
-The current loader class.
|
|
|
|
|
|
-"""
|
|
|
-Loader = DefaultLoader
|
|
|
-if settings.configured:
|
|
|
- Loader = DjangoLoader
|
|
|
-else:
|
|
|
+def resolve_loader(loader):
|
|
|
+ return LOADER_ALIASES.get(loader, loader)
|
|
|
+
|
|
|
+
|
|
|
+def _get_loader_cls(loader):
|
|
|
+ loader = resolve_loader(loader)
|
|
|
+ loader_module = importlib.import_module(loader)
|
|
|
+ return getattr(loader_module, LOADER_CLASS_NAME)
|
|
|
+
|
|
|
+
|
|
|
+def get_loader_cls(loader):
|
|
|
+ """Get loader class by name/alias"""
|
|
|
+ if loader not in _loader_cache:
|
|
|
+ _loader_cache[loader] = _get_loader_cls(loader)
|
|
|
+ return _loader_cache[loader]
|
|
|
+
|
|
|
+
|
|
|
+def _detect_loader():
|
|
|
+ loader = os.environ.get("CELERY_LOADER")
|
|
|
+ if loader:
|
|
|
+ return get_loader_cls(loader)
|
|
|
+
|
|
|
+ if settings.configured:
|
|
|
+ return DjangoLoader
|
|
|
try:
|
|
|
# A settings module may be defined, but Django didn't attempt to
|
|
|
# load it yet. As an alternative to calling the private _setup(),
|
|
@@ -26,23 +48,33 @@ else:
|
|
|
# Platform doesn't support fork()
|
|
|
# XXX On systems without fork, multiprocessing seems to be
|
|
|
# launching the processes in some other way which does
|
|
|
- # not copy the memory of the parent process. This means that any
|
|
|
- # configured env might be lost. This is a hack to make it work
|
|
|
- # on Windows.
|
|
|
+ # not copy the memory of the parent process. This means
|
|
|
+ # any configured env might be lost. This is a hack to make
|
|
|
+ # it work on Windows.
|
|
|
# A better way might be to use os.environ to set the currently
|
|
|
# used configuration method so to propogate it to the "child"
|
|
|
# processes. But this has to be experimented with.
|
|
|
# [asksol/heyman]
|
|
|
try:
|
|
|
settings_mod = os.environ.get("DJANGO_SETTINGS_MODULE",
|
|
|
- "settings")
|
|
|
+ "settings")
|
|
|
project_settings = __import__(settings_mod, {}, {}, [''])
|
|
|
setup_environ(project_settings)
|
|
|
- Loader = DjangoLoader
|
|
|
+ return DjangoLoader
|
|
|
except ImportError:
|
|
|
pass
|
|
|
else:
|
|
|
- Loader = DjangoLoader
|
|
|
+ return DjangoLoader
|
|
|
+
|
|
|
+ return DefaultLoader
|
|
|
+
|
|
|
+"""
|
|
|
+.. class:: Loader
|
|
|
+
|
|
|
+The current loader class.
|
|
|
+
|
|
|
+"""
|
|
|
+Loader = _detect_loader()
|
|
|
|
|
|
"""
|
|
|
.. data:: current_loader
|