1. brianfrantz
  2. beaker

Commits

Ben Bangert  committed 5d9fe20

* Fixed memcached code to use delete_multi on clearing the keys for efficiency
and updated key retrieval to properly store and retrieve None values.

  • Participants
  • Parent commits b660ce5
  • Branches trunk

Comments (0)

Files changed (3)

File CHANGELOG

View file
  • Ignore whitespace
 ================
 
 0.9.1 (**tip**)
+* Fixed memcached code to use delete_multi on clearing the keys for efficiency
+  and updated key retrieval to properly store and retrieve None values.
 * Removing cookie.py and signed cookie middleware, as the environ_key option
   for session middleware provides a close enough setting.
 * Added option to use just cookie-based sessions without requiring

File beaker/ext/memcached.py

View file
  • Ignore whitespace
     def close(self, *args, **params):pass
 
     def __getitem__(self, key):
+        if not self.has_key(key):
+            raise KeyError(key)
         key = key.replace(' ', '\302\267')
-        value = self.mc.get(self.namespace + "_" + key)
-        if value is None:
-            raise KeyError(key)
-        return value
+        return self.mc.get(self.namespace + "_" + key)
 
     def __contains__(self, key):
-        key = key.replace(' ', '\302\267')
-        return self.mc.get(self.namespace + "_" + key) is not None
+        return self.has_key(key)
 
     def has_key(self, key):
         key = key.replace(' ', '\302\267')
-        return self.mc.get(self.namespace + "_" + key) is not None
+        keys = self.mc.get(self.namespace + ':keys') or {}
+        return key in keys
 
     def __setitem__(self, key, value):
         key = key.replace(' ', '\302\267')
     def do_remove(self):
         keys = self.mc.get(self.namespace + ':keys')
         if keys is not None:
-            for key in keys:
-                self.mc.delete(self.namespace + '_' + key)
-            self.mc.delete(self.namespace + ':keys')
+            delete_keys = [self.namespace + '_' + x for x in keys]
+            delete_keys.append(self.namespace + ':keys')
+            self.mc.delete_multi(delete_keys)
     
     def keys(self):
         keys = self.mc.get(self.namespace + ':keys')

File tests/test_memcached.py

View file
  • Ignore whitespace
     start_response('200 OK', [('Content-type', 'text/plain')])
     return ['The current value is: %s' % cache.get_value('value')]
 
+def using_none_app(environ, start_response):
+    extra_args = {}
+    clear = False
+    if environ.get('beaker.clear'):
+        clear = True
+    extra_args['type'] = 'ext:memcached'
+    extra_args['url'] = mc_url
+    extra_args['data_dir'] = './cache'
+    cache = environ['beaker.cache'].get_cache('testcache', **extra_args)
+    if clear:
+        cache.clear()
+    try:
+        value = cache.get_value('value')
+    except:
+        value = 10
+    cache.set_value('value', None)
+    start_response('200 OK', [('Content-type', 'text/plain')])
+    return ['The current value is: %s' % value]
+
+
 def cache_manager_app(environ, start_response):
     cm = environ['beaker.cache']
     cm.get_cache('test')['test_key'] = 'test value'
     res = app.get('/')
     assert 'test_key is: test value' in res
     assert 'test_key cleared' in res
-    
+
+def test_store_none():
+    app = TestApp(CacheMiddleware(using_none_app))
+    res = app.get('/', extra_environ={'beaker.clear':True})
+    assert 'current value is: 10' in res
+    res = app.get('/')
+    assert 'current value is: None' in res