Commits

Gael Pasgrimaud  committed 6477800

add docs / tests

  • Participants
  • Parent commits 857e30c

Comments (0)

Files changed (5)

 var/
 develop-eggs
 docs/_build/
+docs/modules/
 cache/
 .installed.cfg
 *.egg-info

File antistress/cache.py

 
 log = logging.getLogger(__name__)
 
-class Cache(object):
+class CacheMiddleware(object):
+    """A cache middleware.
+    You can use ``environ['http_cache.purge'](*paths)`` in your application
+    code to purge some cache values
+    """
 
-    def __init__(self, app, paths, cache_qs=False, debug=False, **kwargs):
+    def __init__(self, app, paths, cache_qs=False, debug=False, **global_cache_options):
         self.application = app
-        self.manager = CacheManager(**kwargs)
+        self.manager = CacheManager(**global_cache_options)
         self.paths = paths
         log.debug('cache_paths: %s', paths)
         self.cache_qs = cache_qs
         self.debug = debug
 
     def cache_key(self, req):
-        """return the cache key. You may subclass it to take care of cookies or whatever
+        """return the cache key. You may subclass it to take care of cookies or
+        whatever
         """
         if self.cache_qs and req.query_string:
             return '%s?%s' % (req.path_info, req.query_string)
                 return namespace, opts
 
     def update_response(self, req, resp, opts):
-        """update expire/cache headers
+        """Update expire/cache headers before caching the request.
         """
         if 'expire' in opts and not resp.expires:
             resp.cache_expires(opts.get('expire'))
 
     def purge(self, req, key, namespace, opts):
+        """Purge a request from cache. If the backend does not support keys
+        matching then purge the whole cache
+        """
         cache = self.manager.get_cache(namespace, **opts)
         values = []
         try:
         return resp
 
     def cache(self, req, key, namespace, opts):
+        """Get a request from cache or set it if not already cached
+        """
         cache = self.manager.get_cache(namespace,  **opts)
         try:
             resp = cache.get(key)
         return self.cache(req, key, *must_cache)(environ, start_response)
 
 def deserialize_path(line):
+    """Deserialize a path config value:
+
+    .. sourcecode:: py
+
+        >>> deserialize_path('/cache/* expire:10') #doctest: +ELLIPSIS
+        [('/cache/*', True, <_sre.SRE_Pattern ...>), {'expire': 10}]
+
+        >>> deserialize_path('!/cache/* expire:100 type:memcached url:localhost:11211') #doctest: +ELLIPSIS
+        [('!/cache/*', False, <_sre.SRE_Pattern ...>), {'url': 'localhost:11211', 'expire': 100, 'type': 'memcached'}]
+
+    """
     values = line.split()
     namespace = path = values.pop(0)
     if path.startswith('!'):
     return [path, cache_opts]
 
 def make_cache(app, global_conf, **local_conf):
+    """Paste entry_point"""
     paths = local_conf.pop('cache_paths')
     paths = [deserialize_path(p.strip()) for p in paths.split('\n') if p.strip()]
-    return Cache(app, paths=paths, **local_conf)
+    return CacheMiddleware(app, paths=paths, **local_conf)
 

File antistress/tests.py

 # -*- coding: utf-8 -*-
 from webob import Request, Response, exc
 from webtest import TestApp
-from cache import Cache
+from cache import CacheMiddleware, deserialize_path
 from datetime import datetime
 import tempfile
 import shutil
             if 'type' in kwargs:
                 kwargs['url'] = 'localhost:11211'
                 kwargs['data_dir'] = data_dir
-            cache = Cache(application, **kwargs)
+            kwargs['paths'] = [deserialize_path(p) for p in kwargs.get('paths', ['/cache/* expire:100'])]
+            cache = CacheMiddleware(application, **kwargs)
             app = TestApp(cache)
-            func(app, cache)
+            func(app)
         wrapped.func_name = func.func_name
         return wrapped
     return wrapper
     resp2 = app.get('/cache')
     assert resp1.body != resp2.body, (resp1.body, resp2.body)
 
-@with_app(paths=[('/cache', dict(expire=1))])
-def test_cache_memory(app, cache):
+@with_app(paths=['/cache expire:1'])
+def test_cache_memory(app):
     _test_cache(app)
 
-@with_app(paths=[('/cache', dict(expire=1))], type='file')
-def test_cache_file(app, cache):
+@with_app(paths=['/cache expire:1'], type='file')
+def test_cache_file(app):
     _test_cache(app)
 
-@with_app(paths=[('/cache', dict(expire=1))], type='dbm')
-def test_cache_dbm(app, cache):
+@with_app(paths=['/cache expire:1'], type='dbm')
+def test_cache_dbm(app):
     _test_cache(app)
 
-@with_app(paths=[('/cache', dict(expire=1))], type='memcached')
-def test_cache_memcached(app, cache):
+@with_app(paths=['/cache expire:1'], type='memcached')
+def test_cache_memcached(app):
     _test_cache(app)
 
-@with_app(paths=[('/cache/*', dict(expire=100))])
-def test_purge_memory(app, cache):
+@with_app()
+def test_purge_memory(app):
     for i in range(3):
         resp = app.get('/cache/%i' % i)
     check = app.get('/cache/2')
     resp = app.get('/cache/0')
     assert check.body != resp.body
 
-@with_app(paths=[('/cache/*', dict(expire=100))], type='file')
-def test_purge_file(app, cache):
+@with_app(type='file')
+def test_purge_file(app):
     for i in range(3):
         resp = app.get('/cache/%i' % i)
     check = app.get('/cache/2')
     resp = app.get('/cache/0')
     assert check.body != resp.body
 
-@with_app(paths=[('/cache/*', dict(expire=100))], type='dbm')
-def test_purge_dbm(app, cache):
+@with_app(type='dbm')
+def test_purge_dbm(app):
     for i in range(3):
         resp = app.get('/cache/%i' % i)
     check = app.get('/cache/2')
     resp = app.get('/cache/0')
     assert check.body != resp.body
 
-@with_app(paths=[('/cache/*', dict(expire=100))], type='memcached')
-def test_purge_memcached(app, cache):
+@with_app(type='memcached')
+def test_purge_memcached(app):
     for i in range(3):
         resp = app.get('/cache/%i' % i)
     check = app.get('/cache/2')
     resp = app.get('/cache/0')
     assert check.body != resp.body
 
-@with_app(paths=[('/cache*', dict(expire=100))])
-def test_purge_http(app, cache):
+@with_app()
+def test_purge_http(app):
     for i in range(3):
         app.get('/cache/%i' % i)
 
-    resp = app._gen_request('PURGE', '/cache')
+    resp = app._gen_request('PURGE', '/cache/')
     resp.mustcontain('/cache/0', '/cache/1', '/cache/2')
 
 

File buildout.cfg

     restkit
     PasteScript
     Sphinx
+    rstctl
     nose
-interpreter=py26
-[DEFAULT]
-cache_file = expire:3600 type:file 
-
 [server:main]
 use = egg:Paste#http
 port = 5000
 use = egg:AntiStress
 data_dir = %(here)s/cache
 cache_paths = 
-    ^/(_.*|.*\.(css|js)) %(cache_file)s
-    /* expire:60
+    ^/(_.*|.*\.(css|js)) expire:3600 type:file
+    /.*\.html expire:60
 
 [app:app]
 use = egg:restkit#host_proxy