Explorar o código

Skeleton for the ability to select different backends for different actions,
e.g using the database backend for periodic tasks, while using tyrant for
storing results.

Ask Solem %!s(int64=16) %!d(string=hai) anos
pai
achega
fa3c19c271

+ 36 - 2
celery/backends/__init__.py

@@ -4,7 +4,11 @@ from django.conf import settings
 import sys
 
 DEFAULT_BACKEND = "database"
+DEFAULT_PERIODIC_STATUS_BACKEND = "database"
 CELERY_BACKEND = getattr(settings, "CELERY_BACKEND", DEFAULT_BACKEND)
+CELERY_PERIODIC_STATUS_BACKEND = getattr(settings,
+                                    "CELERY_PERIODIC_STATUS_BACKEND",
+                                    DEFAULT_PERIODIC_STATUS_BACKEND)
 
 
 def get_backend_cls(backend):
@@ -31,13 +35,35 @@ get_default_backend_cls = partial(get_backend_cls, CELERY_BACKEND)
 
 
 """
-.. class:: DefaultBackend
+.. function:: get_default_periodicstatus_backend_cls()
 
-    The backend class specified in :setting:`CELERY_BACKEND`.
+    Get the backend class specified in
+    :settings:`CELERY_PERIODIC_STATUS_BACKEND`.
+
+"""
+get_default_periodicstatus_backend_cls = partial(get_backend_cls,
+                                            CELERY_PERIODIC_STATUS_BACKEND)
+
+
+"""
+.. class:: DefaultBackend
+    
+    The default backend class used for storing task results and status,
+    specified in :setting:`CELERY_BACKEND`.
 
 """
 DefaultBackend = get_default_backend_cls()
 
+
+"""
+.. class:: DefaultPeriodicStatusBackend
+
+    The default backend for storing periodic task metadata, specified
+    in :setting:`CELERY_PERIODIC_STATUS_BACKEND`.
+
+"""
+DefaultPeriodicStatusBackend = get_default_periodicstatus_backend_cls()
+
 """
 .. data:: default_backend
 
@@ -45,3 +71,11 @@ DefaultBackend = get_default_backend_cls()
 
 """
 default_backend = DefaultBackend()
+
+"""
+.. data:: default_periodic_status_backend
+
+    An instance of :class:`DefaultPeriodicStatusBackend`.
+
+"""
+default_periodic_status_backend = DefaultPeriodicStatusBackend()

+ 4 - 3
celery/backends/base.py

@@ -80,12 +80,13 @@ class UnpickleableExceptionWrapper(Exception):
 class BaseBackend(object):
     """The base backend class. All backends should inherit from this."""
 
+    capabilities = []
     UnpickleableExceptionWrapper = UnpickleableExceptionWrapper
 
     def store_result(self, task_id, result, status):
         """Store the result and status of a task."""
         raise NotImplementedError(
-                "Backends must implement the store_result method")
+                "store_result is not supported by this backend.")
 
     def mark_as_done(self, task_id, result):
         """Mark task as successfully executed."""
@@ -130,7 +131,7 @@ class BaseBackend(object):
     def get_status(self, task_id):
         """Get the status of a task."""
         raise NotImplementedError(
-                "Backends must implement the get_status method")
+                "get_status is not supported by this backend.")
 
     def prepare_result(self, result):
         """Prepare result for storage."""
@@ -141,7 +142,7 @@ class BaseBackend(object):
     def get_result(self, task_id):
         """Get the result of a task."""
         raise NotImplementedError(
-                "Backends must implement the get_result method")
+                "get_result is not supported by this backend.")
 
     def is_done(self, task_id):
         """Returns ``True`` if the task was successfully executed."""

+ 2 - 0
celery/backends/cache.py

@@ -10,6 +10,8 @@ except ImportError:
 class Backend(BaseBackend):
     """Backend using the Django cache framework to store task metadata."""
 
+    capabilities = ["ResultStore"]
+
     def __init__(self, *args, **kwargs):
         super(Backend, self).__init__(*args, **kwargs)
         self._cache = {}

+ 8 - 1
celery/backends/database.py

@@ -1,15 +1,22 @@
 """celery.backends.database"""
-from celery.models import TaskMeta
+from celery.models import TaskMeta, PeriodicTaskMeta
 from celery.backends.base import BaseBackend
 
 
 class Backend(BaseBackend):
     """The database backends. Using Django models to store task metadata."""
 
+    capabilities = ["ResultStore", "PeriodicStatus"]
+
     def __init__(self, *args, **kwargs):
         super(Backend, self).__init__(*args, **kwargs)
         self._cache = {}
 
+    def run_periodic_tasks(self):
+        waiting_tasks = PeriodicTaskMeta.objects.get_waiting_tasks()
+        for waiting_task in waiting_tasks:
+            waiting_task.delay()
+
     def store_result(self, task_id, result, status):
         """Mark task as done (executed)."""
         if status == "DONE":

+ 2 - 0
celery/backends/tyrant.py

@@ -31,6 +31,8 @@ class Backend(BaseBackend):
     tyrant_host = None
     tyrant_port = None
 
+    capabilities = ["ResultStore"]
+
     def __init__(self, tyrant_host=None, tyrant_port=None):
         """Initialize Tokyo Tyrant backend instance.