Commits

Andriy Kornatskyy committed 02008cd

Refactored HTTP cache middleware due to changed contract of cache dependency.

Comments (0)

Files changed (4)

doc/userguide.rst

 * ``cache`` - setup :py:class:`~wheezy.http.cachepolicy.HTTPCachePolicy`.
   Defaults to ``private`` cache policy.
 * ``skip_body`` - doesn't pass response body; content length is set to zero.
-* ``dependency`` - it is used to setup ``CacheDependency`` for given request
+* ``dependency_key`` - it is used to setup dependency for given request
   thus effectively invalidating cached response depending on some application
   logic. It is a hook for integration with `wheezy.caching`_.
 * ``headers`` - list of headers to be returned to browser; the header must
 Cache Contract
 ~~~~~~~~~~~~~~
 
-Cache contract requires just three methods: ``get(key, namespace)``,
-``set(key, value, time, namespace)`` and
-``set_multi(mapping, time, namespace )``. Cache dependency
-requires ``next_key()`` only. Look at `wheezy.caching`_ package for more
-details.
+Cache contract requires: ``get(key, namespace)``,
+``set(key, value, time, namespace)``,
+``set_multi(mapping, time, namespace)`` and
+``incr(self, key, delta=1, namespace=None, initial_value=None)``.
+Look at `wheezy.caching`_ package for more details.
 
 @response_cache
 ~~~~~~~~~~~~~~~
 cache feature to handler. Here is an example that includes also
 ``CacheDependency``::
 
-    from wheezy.caching import CacheDependency
+    from wheezy.caching.patterns import Cached
     from wheezy.http import CacheProfile
     from wheezy.http import response_cache
     from myapp import cache
 
+    cached = Cached(cache, time=15)
     cache_profile = CacheProfile('server', duration=15)
     none_cache_profile = CacheProfile('none', no_store=True)
 
     @response_cache(cache_profile)
     def list_of_goods(request):
         ...
-        response.dependency = CacheDependency('list_of_goods')
+        response.dependency_key = 'list_of_goods:%s:' % catalog_id
         return response
 
     @response_cache(none_cache_profile)
     def change_price(request):
         ...
-        dependency = CacheDependency('list_of_goods')
-        dependency.delete(cache)
+        cached.dependency.delete('list_of_goods:%s:' % catalog_id)
         return response
 
 While ``list_of_goods`` is being cached, ``change_price`` handler

src/wheezy/http/middleware.py

                     self.profiles[middleware_key] = response_cache_profile
                     request_key = response_cache_profile.request_vary.key(
                         request)
-                dependency = response.dependency
+                dependency_key = response.dependency_key
                 response = CacheableResponse(response)
-                if dependency:
+                if dependency_key:
+                    # determine next key for dependency
+                    dependency_key = dependency_key + str(self.cache.incr(
+                        dependency_key, 1,
+                        response_cache_profile.namespace, 0))
                     self.cache.set_multi({
                         request_key: response,
-                        dependency.next_key(
-                            response_cache_profile.namespace
-                        ): request_key},
+                        dependency_key: request_key},
                         response_cache_profile.duration,
                         '',
                         response_cache_profile.namespace)
             response.cache_profile = profile
             if policy is None:
                 response.cache_policy = profile.cache_policy()
-        if 'wheezy.http.cache_dependency' in environ:
-            response.dependency = environ['wheezy.http.cache_dependency']
+        if 'wheezy.http.cache_dependency_key' in environ:
+            response.dependency_key = environ[
+                'wheezy.http.cache_dependency_key']
         return response
 
 

src/wheezy/http/response.py

     cache_policy = None
     cache_profile = None
     skip_body = False
-    dependency = None
+    dependency_key = None
 
     def __init__(self, content_type='text/html; charset=UTF-8',
                  encoding='UTF-8'):

src/wheezy/http/tests/test_middleware.py

         """ HTTP response:
             1. status codes is 200
             2. has cache profile
-            3. has cache dependency.
+            3. has cache dependency key.
         """
         from wheezy.http.cache import CacheableResponse
         from wheezy.http.cacheprofile import CacheProfile
         self.response.status_code = 200
         self.response.cache_profile = CacheProfile('server', duration=60)
-        mock_dependency = Mock()
-        mock_dependency.next_key.return_value = 'x'
-        self.response.dependency = mock_dependency
+        self.response.dependency_key = 'master_key'
 
         response = self.middleware(self.mock_request, self.mock_following)
 
         self.mock_following.assert_called_once_with(self.mock_request)
         assert isinstance(response, CacheableResponse)
+        self.mock_cache.incr.assert_called_once_with('master_key', 1, None, 0)
         assert self.mock_cache.set_multi.called
 
     def test_cacheprofile_is_known(self):
         response = middleware(request, lambda r: response)
         assert not response.cache_policy
         assert not response.cache_profile
-        assert not response.dependency
+        assert not response.dependency_key
 
     def test_cache_policy(self):
         """ Test cache_policy adapter.
         middleware = EnvironCacheAdapterMiddleware()
         request = HTTPRequest({
             'REQUEST_METHOD': 'GET',
-            'wheezy.http.cache_dependency': 'dependency'
+            'wheezy.http.cache_dependency_key': 'master_key'
         }, None, None)
         response = HTTPResponse()
         response = middleware(request, lambda r: response)
-        assert 'dependency' == response.dependency
+        assert 'master_key' == response.dependency_key