Преглед на файлове

Support setting custom loader with the CELERY_LOADER environment variable.

Ask Solem преди 15 години
родител
ревизия
4ae06cec8f
променени са 1 файла, в които са добавени 46 реда и са изтрити 14 реда
  1. 46 14
      celery/loaders/__init__.py

+ 46 - 14
celery/loaders/__init__.py

@@ -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