Andriy Kornatskyy avatar Andriy Kornatskyy committed e79fe18

Refactored cache patterns and wraps to a single actor Cached with all specializations.

Comments (0)

Files changed (2)

src/wheezy/caching/patterns.py

 from time import time
 
 
-def get_or_add(key, create_factory, dependency_factory=None,
-               time=0, namespace=None, cache=None):
-    """ Cache Pattern: get an item by *key* from *cache* and
-        if it is not available use *create_factory* to aquire one.
-        If result is not `None` use cache `add` operation to store
-        result and if operation succeed use *dependency_factory*
-        to get an instance of `CacheDependency` to add *key* to it.
+class Cached(object):
+    """ Specializes access to cache by using a number of common settings
+        for various cache operations and patterns.
     """
-    result = cache.get(key, namespace)
-    if result is not None:
+
+    def __init__(self, cache, key_builder=None,
+                 time=0, namespace=None,
+                 timeout=10, key_prefix='one_pass:'):
+        self.cache = cache
+        self.key_builder = key_builder
+        self.time = time
+        self.namespace = namespace
+        self.timeout = timeout
+        self.key_prefix = key_prefix
+
+    def set(self, key, value, dependency=None):
+        """ Sets a key's value, regardless of previous contents
+            in cache. If *dependency* is specified the *key* is added.
+        """
+        succeed = self.cache.set(key, value, self.time, self.namespace)
+        if dependency:
+            dependency.add(key, self.namespace)
+        return succeed
+
+    def set_multi(self, mapping, key_prefix=''):
+        """ Set multiple keys' values at once.
+        """
+        return self.cache.set_multi(mapping, self.time, key_prefix,
+                                    self.namespace)
+
+    def add(self, key, value, dependency=None):
+        """ Sets a key's value, if and only if the item is not
+            already. If *dependency* is specified the *key* is added.
+        """
+        succeed = self.cache.add(key, value, self.time, self.namespace)
+        if succeed and dependency:
+            dependency.add(key, self.namespace)
+        return succeed
+
+    def add_multi(self, mapping, key_prefix=''):
+        """ Adds multiple values at once, with no effect for keys
+            already in cache.
+        """
+        return self.cache.add_multi(mapping, self.time, key_prefix,
+                                    self.namespace)
+
+    def replace(self, key, value):
+        """ Replaces a key's value, failing if item isn't already.
+        """
+        return self.cache.replace(key, value, self.time, self.namespace)
+
+    def replace_multi(self, mapping, key_prefix=''):
+        """ Replaces multiple values at once, with no effect for
+            keys not in cache.
+        """
+        return self.cache.replace_multi(mapping, self.time, key_prefix,
+                                        self.namespace)
+
+    def get(self, key):
+        """ Looks up a single key.
+        """
+        return self.cache.get(key, self.namespace)
+
+    def get_multi(self, keys, key_prefix=''):
+        """ Looks up multiple keys from cache in one operation.
+            This is the recommended way to do bulk loads.
+        """
+        return self.cache.get_multi(keys, key_prefix, self.namespace)
+
+    def delete(self, key, seconds=0):
+        """ Deletes a key from cache.
+        """
+        return self.cache.delete(key, seconds, self.namespace)
+
+    def delete_multi(self, keys, seconds=0, key_prefix=''):
+        """ Delete multiple keys at once.
+        """
+        return self.cache.delete_multi(keys, seconds, key_prefix,
+                                       self.namespace)
+
+    def incr(self, key, delta=1, initial_value=None):
+        """ Atomically increments a key's value.
+        """
+        return self.cache.incr(key, delta, self.namespace, initial_value)
+
+    def decr(self, key, delta=1, initial_value=None):
+        """ Atomically decrements a key's value.
+        """
+        return self.cache.decr(key, delta, self.namespace, initial_value)
+
+    def get_or_add(self, key, create_factory, dependency_factory):
+        """ Cache Pattern: get an item by *key* from *cache* and
+            if it is not available use *create_factory* to aquire one.
+            If result is not `None` use cache `add` operation to store
+            result and if operation succeed use *dependency_factory*
+            to get an instance of `CacheDependency` to add *key* to it.
+        """
+        result = self.cache.get(key, self.namespace)
+        if result is not None:
+            return result
+        result = create_factory()
+        if result is not None:
+            succeed = self.cache.add(key, result, self.time, self.namespace)
+            if succeed and dependency_factory is not None:
+                dependency = dependency_factory()
+                dependency.add(key, self.namespace)
         return result
-    result = create_factory()
-    if result is not None:
-        succeed = cache.add(key, result, time, namespace)
-        if succeed and dependency_factory is not None:
-            dependency = dependency_factory()
-            dependency.add(key, namespace)
-    return result
 
+    def wraps_get_or_add(self, wrapped):
+        """ Returns specialized decorator for `get_or_add` cache
+            pattern.
 
-def partial_get_or_add(cache, time=0, namespace=None):
-    """ Specializes `get_or_add` cache pattern to::
+            Example::
 
-            get_or_add(key, create_factory, dependency_factory=None)
-    """
-    def get_or_add_wrapper(key, create_factory, dependency_factory=None):
-        return get_or_add(
-            key, create_factory, dependency_factory,
-            time, namespace, cache)
-    return get_or_add_wrapper
+                kb = key_builder('repo')
+                cached = Cached(cache, kb, time=60)
 
+                @cached.wraps_get_or_add
+                def list_items(self, locale):
+                    pass
+        """
+        make_key = self.key_builder(wrapped)
 
-def wraps_get_or_add(cache, key_builder, time=0, namespace=None):
-    """ Returns specialized decorator for `get_or_add` cache
-        pattern.
-
-        Example::
-
-            kb = key_builder('repo')
-            cached = wraps_get_or_add(cache, kb, time=100)
-
-            @cached
-            def list_items(self, locale):
-                pass
-    """
-    def decorate(wrapped):
-        make_key = key_builder(wrapped)
-
-        def get_or_add(*args, **kwargs):
+        def get_or_add_wrapper(*args, **kwargs):
             key = make_key(*args, **kwargs)
-            result = cache.get(key, namespace)
+            result = self.cache.get(key, self.namespace)
             if result is not None:
                 return result
             result = wrapped(*args, **kwargs)
             if result is not None:
-                cache.add(key, result, time, namespace)
+                self.cache.add(key, result, self.time, self.namespace)
             return result
-        return get_or_add
-    return decorate
+        return get_or_add_wrapper
 
+    def get_or_set(self, key, create_factory, dependency_factory=None):
+        """ Cache Pattern: get an item by *key* from *cache* and
+            if it is not available use *create_factory* to aquire one.
+            If result is not `None` use cache `set` operation to store
+            result and use *dependency_factory* to get an instance of
+            `CacheDependency` to add *key* to it.
+        """
+        result = self.cache.get(key, self.namespace)
+        if result is not None:
+            return result
+        result = create_factory()
+        if result is not None:
+            self.cache.set(key, result, self.time, self.namespace)
+            if dependency_factory is not None:
+                dependency = dependency_factory()
+                dependency.add(key, self.namespace)
+        return result
 
-def get_or_set(key, create_factory, dependency_factory=None,
-               time=0, namespace=None, cache=None):
-    """ Cache Pattern: get an item by *key* from *cache* and
-        if it is not available use *create_factory* to aquire one.
-        If result is not `None` use cache `set` operation to store
-        result and use *dependency_factory* to get an instance of
-        `CacheDependency` to add *key* to it.
-    """
-    result = cache.get(key, namespace)
-    if result is not None:
-        return result
-    result = create_factory()
-    if result is not None:
-        cache.set(key, result, time, namespace)
-        if dependency_factory is not None:
-            dependency = dependency_factory()
-            dependency.add(key, namespace)
-    return result
+    def __call__(self, wrapped):
+        return self.wraps_get_or_set(wrapped)
 
+    def wraps_get_or_set(self, wrapped):
+        """ Returns specialized decorator for `get_or_set` cache
+            pattern.
 
-def partial_get_or_set(cache, time=0, namespace=None):
-    """ Specializes `get_or_set` cache pattern to::
+            Example::
 
-            get_or_set(key, create_factory, dependency_factory=None)
-    """
-    def get_or_set_wrapper(key, create_factory, dependency_factory=None):
-        return get_or_set(
-            key, create_factory, dependency_factory,
-            time, namespace, cache)
-    return get_or_set_wrapper
+                kb = key_builder('repo')
+                cached = Cached(cache, kb, time=60)
 
+                @cached
+                # or @cached.wraps_get_or_set
+                def list_items(self, locale):
+                    pass
+        """
+        make_key = self.key_builder(wrapped)
 
-def wraps_get_or_set(cache, key_builder, time=0, namespace=None):
-    """ Returns specialized decorator for `get_or_set` cache
-        pattern.
-
-        Example::
-
-            kb = key_builder('repo')
-            cached = wraps_get_or_set(cache, kb, time=100)
-
-            @cached
-            def list_items(self, locale):
-                pass
-    """
-    def decorate(wrapped):
-        make_key = key_builder(wrapped)
-
-        def get_or_set(*args, **kwargs):
+        def get_or_set_wrapper(*args, **kwargs):
             key = make_key(*args, **kwargs)
-            result = cache.get(key, namespace)
+            result = self.cache.get(key, self.namespace)
             if result is not None:
                 return result
             result = wrapped(*args, **kwargs)
             if result is not None:
-                cache.set(key, result, time, namespace)
+                self.cache.set(key, result, self.time, self.namespace)
             return result
-        return get_or_set
-    return decorate
+        return get_or_set_wrapper
 
+    def one_pass_create(self, key, create_factory, dependency_factory=None):
+        """ Cache Pattern: try enter one pass: (1) if entered
+            use *create_factory* to get a value if result is not `None`
+            use cache `set` operation to store result and use
+            *dependency_factory* to get an instance of `CacheDependency`
+            to add *key* to it; (2) if not entered `wait` until one
+            pass is available and it is not timed out get an item by *key*
+            from *cache*.
+        """
+        result = None
+        one_pass = OnePass(self.cache, self.key_prefix + key,
+                           self.timeout, self.namespace)
+        try:
+            one_pass.__enter__()
+            if one_pass.acquired:
+                result = create_factory()
+                if result is not None:
+                    self.cache.set(key, result, self.time, self.namespace)
+                    if dependency_factory is not None:
+                        dependency = dependency_factory()
+                        dependency.add(key, self.namespace)
+            elif one_pass.wait():
+                result = self.cache.get(key, self.namespace)
+        finally:
+            one_pass.__exit__(None, None, None)
+        return result
 
-def one_pass_create(key, create_factory, dependency_factory=None,
-                    time=0, namespace=None, cache=None,
-                    timeout=10, key_prefix='one_pass:'):
-    """ Cache Pattern: try enter one pass: (1) if entered
-        use *create_factory* to get a value if result is not `None`
-        use cache `set` operation to store result and use
-        *dependency_factory* to get an instance of `CacheDependency`
-        to add *key* to it; (2) if not entered `wait` until one
-        pass is available and it is not timed out get an item by *key*
-        from *cache*.
-    """
-    result = None
-    one_pass = OnePass(cache, key_prefix + key, timeout, namespace)
-    try:
-        one_pass.__enter__()
-        if one_pass.acquired:
-            result = create_factory()
-            if result is not None:
-                cache.set(key, result, time, namespace)
-                if dependency_factory is not None:
-                    dependency = dependency_factory()
-                    dependency.add(key, namespace)
-        elif one_pass.wait():
-            result = cache.get(key, namespace)
-    finally:
-        one_pass.__exit__(None, None, None)
-    return result
-
-
-def partial_one_pass_create(cache, time=0, namespace=None,
-                            timeout=10, key_prefix='one_pass:'):
-    """ Specializes `one_pass_create` cache pattern to::
-
-            one_pass_create(key, create_factory, dependency_factory=None)
-    """
-    def one_pass_create_wrapper(key, create_factory, dependency_factory=None):
-        return one_pass_create(
-            key, create_factory, dependency_factory,
-            time, namespace, cache,
-            timeout, key_prefix)
-    return one_pass_create_wrapper
-
-
-def get_or_create(key, create_factory, dependency_factory=None,
-                  time=0, namespace=None, cache=None,
-                  timeout=10, key_prefix='one_pass:'):
-    """ Cache Pattern: get an item by *key* from *cache* and
-        if it is not available see `one_pass_create`.
-    """
-    result = cache.get(key, namespace)
-    if result is not None:
-        return result
-    return one_pass_create(key, create_factory, dependency_factory,
-                           time, namespace, cache, timeout, key_prefix)
-
-
-def partial_get_or_create(cache, time=0, namespace=None,
-                          timeout=10, key_prefix='one_pass:'):
-    """ Specializes `get_or_create` cache pattern to::
-
-            get_or_create(key, create_factory, dependency_factory=None)
-    """
-    def get_or_create_wrapper(key, create_factory, dependency_factory=None):
-        result = cache.get(key, namespace)
+    def get_or_create(self, key, create_factory, dependency_factory=None):
+        """ Cache Pattern: get an item by *key* from *cache* and
+            if it is not available see `one_pass_create`.
+        """
+        result = self.cache.get(key, self.namespace)
         if result is not None:
             return result
-        return one_pass_create(
-            key, create_factory, dependency_factory,
-            time, namespace, cache,
-            timeout, key_prefix)
-    return get_or_create_wrapper
+        return self.one_pass_create(key, create_factory, dependency_factory)
 
+    def wraps_get_or_create(self, wrapped):
+        """ Returns specialized decorator for `get_or_create` cache
+            pattern.
 
-def wraps_get_or_create(cache, key_builder, time=0, namespace=None,
-                        timeout=10, key_prefix='one_pass:'):
-    """ Returns specialized decorator for `get_or_create` cache
-        pattern.
+            Example::
 
-        Example::
+                kb = key_builder('repo')
+                cached = Cached(cache, kb, time=60)
 
-            kb = key_builder('repo')
-            cached = wraps_get_or_create(cache, kb, time=100)
+                @cached.wraps_get_or_create
+                def list_items(self, locale):
+                    pass
+        """
+        make_key = self.key_builder(wrapped)
 
-            @cached
-            def list_items(self, locale):
-                pass
-    """
-    def decorate(wrapped):
-        make_key = key_builder(wrapped)
-
-        def get_or_create(*args, **kwargs):
+        def get_or_create_wrapper(*args, **kwargs):
             key = make_key(*args, **kwargs)
-            result = cache.get(key, namespace)
+            result = self.cache.get(key, self.namespace)
             if result is not None:
                 return result
-            return one_pass_create(
-                key, lambda: wrapped(*args, **kwargs), None,
-                time, namespace, cache,
-                timeout, key_prefix)
-        return get_or_create
-    return decorate
-
-
-def key_format(func, key_prefix):
-    """ Returns a key format for *func* and *key_prefix*.
-
-        >>> def list_items(self, locale='en', sort_order=1):
-        ...     pass
-        >>> key_format(list_items, 'repo')
-        'repo-list_items:%r:%r'
-    """
-    argnames = getargspec(func)[0]
-    n = len(argnames)
-    if n and argnames[0] in ('self', 'cls', 'klass'):
-        n -= 1
-    return '%s-%s%s' % (key_prefix, func.__name__, ':%r' * n)
-
-
-def key_formater(key_prefix):
-    """ Specialize a key format with *key_prefix*.
-
-        >>> def list_items(self, locale='en', sort_order=1):
-        ...     pass
-        >>> repo_key_format = key_formater('repo')
-        >>> repo_key_format(list_items)
-        'repo-list_items:%r:%r'
-    """
-    def key_format_wrapper(func):
-        return key_format(func, key_prefix)
-    return key_format_wrapper
-
-
-def key_builder(key_prefix):
-    """ Returns a key builder that allows build a make cache key
-        function at runtime.
-
-        >>> def list_items(self, locale='en', sort_order=1):
-        ...     pass
-
-        >>> repo_key_builder = key_builder('repo')
-        >>> make_key = repo_key_builder(list_items)
-        >>> make_key('self')
-        "repo-list_items:'en':1"
-        >>> make_key('self', 'uk')
-        "repo-list_items:'uk':1"
-        >>> make_key('self', sort_order=0)
-        "repo-list_items:'en':0"
-
-        Here is an example of make key function::
-
-            def key_list_items(self, locale='en', sort_order=1):
-                return "repo-list_items:%r:%r" % (locale, sort_order)
-
-    """
-    def build(func):
-        argnames, varargs, kwargs, defaults = getargspec(func)
-        if defaults:
-            n = len(defaults)
-            args = argnames[:-n]
-            args.extend('%s=%r' % x for x in zip(argnames[-n:], defaults))
-        else:
-            args = argnames
-        if argnames and argnames[0] in ('self', 'cls', 'klass'):
-            argnames = argnames[1:]
-        fname = 'key_' + func.__name__
-        code = 'def %s(%s): return "%s" %% (%s)' % (
-            fname, ', '.join(args), key_format(func, key_prefix),
-            ', '.join(argnames))
-        return compile_source(code, 'keys_' + key_prefix)[fname]
-    return build
+            return self.one_pass_create(key, lambda: wrapped(*args, **kwargs))
+        return get_or_create_wrapper
 
 
 class OnePass(object):
             self.acquired = False
 
 
+def key_format(func, key_prefix):
+    """ Returns a key format for *func* and *key_prefix*.
+
+        >>> def list_items(self, locale='en', sort_order=1):
+        ...     pass
+        >>> key_format(list_items, 'repo')
+        'repo-list_items:%r:%r'
+    """
+    argnames = getargspec(func)[0]
+    n = len(argnames)
+    if n and argnames[0] in ('self', 'cls', 'klass'):
+        n -= 1
+    return '%s-%s%s' % (key_prefix, func.__name__, ':%r' * n)
+
+
+def key_formater(key_prefix):
+    """ Specialize a key format with *key_prefix*.
+
+        >>> def list_items(self, locale='en', sort_order=1):
+        ...     pass
+        >>> repo_key_format = key_formater('repo')
+        >>> repo_key_format(list_items)
+        'repo-list_items:%r:%r'
+    """
+    def key_format_wrapper(func):
+        return key_format(func, key_prefix)
+    return key_format_wrapper
+
+
+def key_builder(key_prefix):
+    """ Returns a key builder that allows build a make cache key
+        function at runtime.
+
+        >>> def list_items(self, locale='en', sort_order=1):
+        ...     pass
+
+        >>> repo_key_builder = key_builder('repo')
+        >>> make_key = repo_key_builder(list_items)
+        >>> make_key('self')
+        "repo-list_items:'en':1"
+        >>> make_key('self', 'uk')
+        "repo-list_items:'uk':1"
+        >>> make_key('self', sort_order=0)
+        "repo-list_items:'en':0"
+
+        Here is an example of make key function::
+
+            def key_list_items(self, locale='en', sort_order=1):
+                return "repo-list_items:%r:%r" % (locale, sort_order)
+
+    """
+    def build(func):
+        argnames, varargs, kwargs, defaults = getargspec(func)
+        if defaults:
+            n = len(defaults)
+            args = argnames[:-n]
+            args.extend('%s=%r' % x for x in zip(argnames[-n:], defaults))
+        else:
+            args = argnames
+        if argnames and argnames[0] in ('self', 'cls', 'klass'):
+            argnames = argnames[1:]
+        fname = 'key_' + func.__name__
+        code = 'def %s(%s): return "%s" %% (%s)' % (
+            fname, ', '.join(args), key_format(func, key_prefix),
+            ', '.join(argnames))
+        return compile_source(code, 'keys_' + key_prefix)[fname]
+    return build
+
+
 # region: internal details
 
 def compile_source(source, name):

src/wheezy/caching/tests/test_patterns.py

 from mock import patch
 
 
+class CachedTestCase(unittest.TestCase):
+
+    def setUp(self):
+        from wheezy.caching.patterns import Cached
+        self.mock_cache = Mock()
+        self.mock_dependency = Mock()
+        self.cached = Cached(self.mock_cache, time=10, namespace='ns')
+
+    def test_set(self):
+        """ Ensure set operation is passed to cache.
+        """
+        self.cached.set('key', 'value')
+        self.mock_cache.set.assert_called_once_with('key', 'value', 10, 'ns')
+
+    def test_set_with_dependency(self):
+        """ Ensure set operation is passed to cache and
+            key added to dependency.
+        """
+        self.cached.set('key', 'value', self.mock_dependency)
+        self.mock_cache.set.assert_called_once_with('key', 'value', 10, 'ns')
+        self.mock_dependency.add.assert_called_once_with('key', 'ns')
+
+    def test_set_multi(self):
+        """ Ensure set_multi operation is passed to cache.
+        """
+        self.cached.set_multi({'key': 'value'}, 'key_prefix')
+        self.mock_cache.set_multi.assert_called_once_with(
+            {'key': 'value'}, 10, 'key_prefix', 'ns')
+
+    def test_add(self):
+        """ Ensure add operation is passed to cache.
+        """
+        self.cached.add('key', 'value')
+        self.mock_cache.add.assert_called_once_with('key', 'value', 10, 'ns')
+
+    def test_add_failed_with_dependency(self):
+        """ Ensure add operation is passed to cache and
+            key added to dependency.
+        """
+        self.mock_cache.add.return_value = False
+        self.cached.add('key', 'value', self.mock_dependency)
+        self.mock_cache.add.assert_called_once_with('key', 'value', 10, 'ns')
+        assert not self.mock_dependency.add.called
+
+    def test_add_with_dependency(self):
+        """ Ensure add operation is passed to cache and
+            key added to dependency.
+        """
+        self.cached.add('key', 'value', self.mock_dependency)
+        self.mock_cache.add.assert_called_once_with('key', 'value', 10, 'ns')
+        self.mock_dependency.add.assert_called_once_with('key', 'ns')
+
+    def test_add_multi(self):
+        """ Ensure add_multi operation is passed to cache.
+        """
+        self.cached.add_multi({'key': 'value'}, 'key_prefix')
+        self.mock_cache.add_multi.assert_called_once_with(
+            {'key': 'value'}, 10, 'key_prefix', 'ns')
+
+    def test_replace(self):
+        """ Ensure replace operation is passed to cache.
+        """
+        self.cached.replace('key', 'value')
+        self.mock_cache.replace.assert_called_once_with(
+            'key', 'value', 10, 'ns')
+
+    def test_replace_multi(self):
+        """ Ensure replace_multi operation is passed to cache.
+        """
+        self.cached.replace_multi({'key': 'value'}, 'key_prefix')
+        self.mock_cache.replace_multi.assert_called_once_with(
+            {'key': 'value'}, 10, 'key_prefix', 'ns')
+
+    def test_get(self):
+        """ Ensure get operation is passed to cache.
+        """
+        self.cached.get('key')
+        self.mock_cache.get.assert_called_once_with('key', 'ns')
+
+    def test_get_multi(self):
+        """ Ensure get_multi operation is passed to cache.
+        """
+        self.cached.get_multi(['key'], 'key_prefix')
+        self.mock_cache.get_multi.assert_called_once_with(
+            ['key'], 'key_prefix', 'ns')
+
+    def test_delete(self):
+        """ Ensure delete operation is passed to cache.
+        """
+        self.cached.delete('key', 0)
+        self.mock_cache.delete.assert_called_once_with('key', 0, 'ns')
+
+    def test_delete_multi(self):
+        """ Ensure delete_multi operation is passed to cache.
+        """
+        self.cached.delete_multi(['key'], 0, 'key_prefix')
+        self.mock_cache.delete_multi.assert_called_once_with(
+            ['key'], 0, 'key_prefix', 'ns')
+
+    def test_incr(self):
+        """ Ensure incr operation is passed to cache.
+        """
+        self.cached.incr('key', 1, 0)
+        self.mock_cache.incr.assert_called_once_with('key', 1, 'ns', 0)
+
+    def test_decr(self):
+        """ Ensure decr operation is passed to cache.
+        """
+        self.cached.decr('key', 1, 0)
+        self.mock_cache.decr.assert_called_once_with('key', 1, 'ns', 0)
+
+
 class OnePassTestCase(unittest.TestCase):
 
     def setUp(self):
         self.mock_create_factory = Mock()
 
     def get_or_add(self, dependency_factory=None):
-        from wheezy.caching.patterns import get_or_add as ga
-        return ga('key', self.mock_create_factory, dependency_factory,
-                  10, 'ns', self.mock_cache)
+        from wheezy.caching.patterns import Cached
+        cached = Cached(self.mock_cache, time=10, namespace='ns')
+        return cached.get_or_add('key', self.mock_create_factory,
+                                 dependency_factory)
 
     def test_found(self):
         """ An item found in cache.
             'key', 'ns')
 
 
-class PartialGetOrAddTestCase(GetOrAddTestCase):
-
-    @patch('wheezy.caching.patterns.get_or_add')
-    def test_partial(self, mock_get_or_add):
-        """ Ensure call defaults.
-        """
-        from wheezy.caching.patterns import partial_get_or_add
-        cached = partial_get_or_add(
-            'cache', time='time', namespace='namespace')
-
-        cached('key', 'create_factory', 'dependency_factory')
-        mock_get_or_add.assert_called_once_with(
-            'key', 'create_factory', 'dependency_factory',
-            'time', 'namespace', 'cache')
-
-
 class WrapsGetOrAddTestCase(GetOrAddTestCase):
 
     def setUp(self):
         self.mock_create_factory = Mock()
 
     def get_or_add(self, dependency_factory=None):
-        from wheezy.caching.patterns import wraps_get_or_add as wga
-        key_builder = lambda f: lambda *args, **kwargs: 'key'
-        return wga(self.mock_cache, key_builder, 10, 'ns')(
-            self.mock_create_factory)()
+        from wheezy.caching.patterns import Cached
+        kb = lambda f: lambda *args, **kwargs: 'key'
+        cached = Cached(self.mock_cache, kb, time=10, namespace='ns')
+        return cached.wraps_get_or_add(self.mock_create_factory)()
 
     def test_has_dependency(self):
         """ Not supported.
         self.mock_create_factory = Mock()
 
     def get_or_set(self, dependency_factory=None):
-        from wheezy.caching.patterns import get_or_set as gs
-        return gs('key', self.mock_create_factory, dependency_factory,
-                  10, 'ns', self.mock_cache)
+        from wheezy.caching.patterns import Cached
+        cached = Cached(self.mock_cache, time=10, namespace='ns')
+        return cached.get_or_set('key', self.mock_create_factory,
+                                 dependency_factory)
 
     def test_found(self):
         """ An item found in cache.
             'key', 'ns')
 
 
-class PartialGetOrSetTestCase(GetOrSetTestCase):
-
-    @patch('wheezy.caching.patterns.get_or_set')
-    def test_partial(self, mock_get_or_set):
-        """ Ensure call defaults.
-        """
-        from wheezy.caching.patterns import partial_get_or_set
-        cached = partial_get_or_set(
-            'cache', time='time', namespace='namespace')
-
-        cached('key', 'create_factory', 'dependency_factory')
-        mock_get_or_set.assert_called_once_with(
-            'key', 'create_factory', 'dependency_factory',
-            'time', 'namespace', 'cache')
-
-
 class WrapsGetOrSetTestCase(GetOrSetTestCase):
 
     def setUp(self):
         self.mock_create_factory = Mock()
 
     def get_or_set(self, dependency_factory=None):
-        from wheezy.caching.patterns import wraps_get_or_set as wgs
-        key_builder = lambda f: lambda *args, **kwargs: 'key'
-        return wgs(self.mock_cache, key_builder, 10, 'ns')(
-            self.mock_create_factory)()
+        from wheezy.caching.patterns import Cached
+        kb = lambda f: lambda *args, **kwargs: 'key'
+        cached = Cached(self.mock_cache, kb, time=10, namespace='ns')
+        return cached.wraps_get_or_set(self.mock_create_factory)()
+
+    def test_has_dependency(self):
+        """ Not supported.
+        """
+        pass
+
+
+class CachedCallTestCase(GetOrSetTestCase):
+
+    def setUp(self):
+        self.mock_cache = Mock()
+        self.mock_create_factory = Mock()
+
+    def get_or_set(self, dependency_factory=None):
+        from wheezy.caching.patterns import Cached
+        kb = lambda f: lambda *args, **kwargs: 'key'
+        cached = Cached(self.mock_cache, kb, time=10, namespace='ns')
+        return cached(self.mock_create_factory)()
 
     def test_has_dependency(self):
         """ Not supported.
         self.mock_create_factory = Mock()
 
     def one_pass_create(self, dependency_factory=None):
-        from wheezy.caching.patterns import one_pass_create as opc
-        return opc('key', self.mock_create_factory, dependency_factory,
-                   10, 'ns', self.mock_cache, 5)
+        from wheezy.caching.patterns import Cached
+        cached = Cached(self.mock_cache, time=10, namespace='ns', timeout=5)
+        return cached.one_pass_create('key', self.mock_create_factory,
+                                      dependency_factory)
 
     def test_create_none(self):
         """ One pass has been entered and create factory returns None.
         assert 'x' == self.one_pass_create()
 
 
-class PartialOnePassCreateTestCase(unittest.TestCase):
-
-    @patch('wheezy.caching.patterns.one_pass_create')
-    def test_partial(self, mock_one_pass_create):
-        """ Ensure call defaults.
-        """
-        from wheezy.caching.patterns import partial_one_pass_create
-        cached = partial_one_pass_create(
-            'cache', time='time', namespace='namespace',
-            timeout='timeout', key_prefix='key_prefix')
-
-        cached('key', 'create_factory', 'dependency_factory')
-        mock_one_pass_create.assert_called_once_with(
-            'key', 'create_factory', 'dependency_factory',
-            'time', 'namespace', 'cache',
-            'timeout', 'key_prefix')
-
-
 class GetOrCreateTestCase(unittest.TestCase):
 
     def setUp(self):
         self.mock_create_factory = Mock()
 
     def get_or_create(self):
-        from wheezy.caching.patterns import get_or_create as gc
-        return gc('key', self.mock_create_factory, None,
-                  10, 'ns', self.mock_cache, 5)
+        from wheezy.caching.patterns import Cached
+        cached = Cached(self.mock_cache, time=10, namespace='ns', timeout=5)
+        return cached.get_or_create('key', self.mock_create_factory)
 
     def test_found(self):
         """ An item found in cache.
         assert 'x' == self.get_or_create()
         self.mock_cache.get.assert_called_once_with('key', 'ns')
 
-    def test_partial_found(self):
-        """ An item found in cache.
-        """
-        from wheezy.caching.patterns import partial_get_or_create
-        self.mock_cache.get.return_value = 'x'
-        cached = partial_get_or_create(
-            self.mock_cache, time='time', namespace='namespace',
-            timeout='timeout', key_prefix='key_prefix')
-
-        assert 'x' == cached('key', None)
-
-
-class PartialGetOrCreateTestCase(GetOrCreateTestCase):
-
-    @patch('wheezy.caching.patterns.one_pass_create')
-    def test_partial(self, mock_one_pass_create):
-        """ Ensure call defaults.
-        """
-        from wheezy.caching.patterns import partial_get_or_create
-        self.mock_cache.get.return_value = None
-        cached = partial_get_or_create(
-            self.mock_cache, time='time', namespace='namespace',
-            timeout='timeout', key_prefix='key_prefix')
-
-        cached('key', 'create_factory', 'dependency_factory')
-        mock_one_pass_create.assert_called_once_with(
-            'key', 'create_factory', 'dependency_factory',
-            'time', 'namespace', self.mock_cache,
-            'timeout', 'key_prefix')
-
 
 class WrapsGetOrCreateTestCase(GetOrCreateTestCase):
 
         self.mock_create_factory = Mock()
 
     def get_or_create(self, dependency_factory=None):
-        from wheezy.caching.patterns import wraps_get_or_create as wgc
-        key_builder = lambda f: lambda *args, **kwargs: 'key'
-        return wgc(self.mock_cache, key_builder, 10, 'ns', 5)(
-            self.mock_create_factory)()
+        from wheezy.caching.patterns import Cached
+        kb = lambda f: lambda *args, **kwargs: 'key'
+        cached = Cached(self.mock_cache, kb, time=10, namespace='ns',
+                        timeout=5)
+        return cached.wraps_get_or_create(self.mock_create_factory)()
 
 
 class KeyBuilderTestCase(unittest.TestCase):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.