Pārlūkot izejas kodu

celery.utils.functional: memoize() decorator using LRUCache by default

Ask Solem 14 gadi atpakaļ
vecāks
revīzija
e6b240501e
2 mainītis faili ar 50 papildinājumiem un 11 dzēšanām
  1. 8 11
      celery/backends/__init__.py
  2. 42 0
      celery/utils/functional.py

+ 8 - 11
celery/backends/__init__.py

@@ -1,6 +1,7 @@
 from celery import current_app
 from celery import current_app
 from celery.local import Proxy
 from celery.local import Proxy
 from celery.utils import get_cls_by_name
 from celery.utils import get_cls_by_name
+from celery.utils.functional import memoize
 
 
 BACKEND_ALIASES = {
 BACKEND_ALIASES = {
     "amqp": "celery.backends.amqp.AMQPBackend",
     "amqp": "celery.backends.amqp.AMQPBackend",
@@ -13,22 +14,18 @@ BACKEND_ALIASES = {
     "disabled": "celery.backends.base.DisabledBackend",
     "disabled": "celery.backends.base.DisabledBackend",
 }
 }
 
 
-_backend_cache = {}
-
 
 
+@memoize(100)
 def get_backend_cls(backend=None, loader=None):
 def get_backend_cls(backend=None, loader=None):
     """Get backend class by name/alias"""
     """Get backend class by name/alias"""
     backend = backend or "disabled"
     backend = backend or "disabled"
     loader = loader or current_app.loader
     loader = loader or current_app.loader
-    if backend not in _backend_cache:
-        aliases = dict(BACKEND_ALIASES, **loader.override_backends)
-        try:
-            _backend_cache[backend] = get_cls_by_name(backend, aliases)
-        except ValueError, exc:
-            raise ValueError("Unknown result backend: %r.  "
-                             "Did you spell it correctly?  (%s)" % (backend,
-                                                                    exc))
-    return _backend_cache[backend]
+    aliases = dict(BACKEND_ALIASES, **loader.override_backends)
+    try:
+        return get_cls_by_name(backend, aliases)
+    except ValueError, exc:
+        raise ValueError("Unknown result backend: %r.  "
+                         "Did you spell it correctly?  (%s)" % (backend, exc))
 
 
 
 
 # deprecate this.
 # deprecate this.

+ 42 - 0
celery/utils/functional.py

@@ -0,0 +1,42 @@
+from __future__ import absolute_import, with_statement
+
+from functools import wraps
+from threading import Lock
+
+from celery.datastructures import LRUCache
+
+KEYWORD_MARK = object()
+
+
+def memoize(maxsize=None, Cache=LRUCache):
+
+    def _memoize(fun):
+        mutex = Lock()
+        cache = Cache(limit=maxsize)
+
+        @wraps(fun)
+        def _M(*args, **kwargs):
+            key = args + (KEYWORD_MARK, ) + tuple(sorted(kwargs.iteritems()))
+            try:
+                with mutex:
+                    value = cache[key]
+            except KeyError:
+                value = fun(*args, **kwargs)
+                _M.misses += 1
+                with mutex:
+                    cache[key] = value
+            else:
+                _M.hits += 1
+            return value
+
+        def clear():
+            """Clear the cache and reset cache statistics."""
+            cache.clear()
+            _M.hits = _M.misses = 0
+
+        _M.hits = _M.misses = 0
+        _M.clear = clear
+        _M.original_func = fun
+        return _M
+
+    return _memoize