functional.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. # -*- coding: utf-8 -*-
  2. """
  3. celery.utils.functional
  4. ~~~~~~~~~~~~~~~~~~~~~~~
  5. Utilities for functions.
  6. :copyright: (c) 2009 - 2011 by Ask Solem.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. from __future__ import absolute_import
  10. from __future__ import with_statement
  11. from functools import wraps
  12. from threading import Lock
  13. try:
  14. from collections import Sequence
  15. except ImportError:
  16. # <= Py2.5
  17. Sequence = (list, tuple) # noqa
  18. from celery.datastructures import LRUCache
  19. KEYWORD_MARK = object()
  20. def maybe_list(l):
  21. if isinstance(l, Sequence):
  22. return l
  23. return [l]
  24. def memoize(maxsize=None, Cache=LRUCache):
  25. def _memoize(fun):
  26. mutex = Lock()
  27. cache = Cache(limit=maxsize)
  28. @wraps(fun)
  29. def _M(*args, **kwargs):
  30. key = args + (KEYWORD_MARK, ) + tuple(sorted(kwargs.iteritems()))
  31. try:
  32. with mutex:
  33. value = cache[key]
  34. except KeyError:
  35. value = fun(*args, **kwargs)
  36. _M.misses += 1
  37. with mutex:
  38. cache[key] = value
  39. else:
  40. _M.hits += 1
  41. return value
  42. def clear():
  43. """Clear the cache and reset cache statistics."""
  44. cache.clear()
  45. _M.hits = _M.misses = 0
  46. _M.hits = _M.misses = 0
  47. _M.clear = clear
  48. _M.original_func = fun
  49. return _M
  50. return _memoize