Commits

Ben Bangert committed 7ba1c09

Increased robustness of key deleting

Comments (0)

Files changed (2)

beaker/ext/memcached.py

         self.mc.set(self.namespace + "_" + key, value)
 
     def __delitem__(self, key):
-        key = key.replace(' ', '\302\267')
-        keys = self.mc.get(self.namespace + ':keys')
-        try:
-            del keys[key]
-            self.mc.delete(self.namespace + "_" + key)
-            self.mc.set(self.namespace + ':keys', keys)
-        except KeyError:
-            raise
+        cache_key = key.replace(' ', '\302\267')
+        ns_key = self.namespace + '_' + cache_key
+        all_key = self.namespace + ':keys'
+        keys = [ns_key, all_key]
+        key_dict = self.mc.get_multi(keys)
+        if ns_key in key_dict:
+            self.mc.delete(ns_key)
+            mem_keys = key_dict.get(all_key, {})
+            if cache_key in mem_keys:
+                del mem_keys[cache_key]
+                self.mc.set(all_key, mem_keys)
+        else:
+            raise KeyError
 
     def do_remove(self):
         keys = self.mc.get(self.namespace + ':keys')

tests/test_memcached.py

     cache.remove_value("test")
     assert not cache.has_key("test")
 
-def test_memcache_dropping_keys():
+def test_dropping_keys():
     cache = Cache('test', data_dir='./cache', url=mc_url, type='ext:memcached')
     cache.set_value('test', 20)
     cache.set_value('fred', 10)
     assert cache.has_key('fred')
     
     # Nuke the keys dict, it might die, who knows
-    cache._containers['test'].namespacemanager.mc.delete('test:keys')
+    cache._containers['fred'].namespacemanager.mc.delete('test:keys')
     assert cache.has_key('fred')
     
     # And we still need clear to work, even if it won't work well
     cache.clear()
 
+def test_deleting_keys():
+    cache = Cache('test', data_dir='./cache', url=mc_url, type='ext:memcached')
+    cache.set_value('test', 20)
+    
+    # Nuke the keys dict, it might die, who knows
+    cache._containers['test'].namespacemanager.mc.delete('test:keys')
+    
+    assert cache.has_key('test')
+    
+    # make sure we can still delete keys even though our keys dict got nuked
+    del cache['test']
+    
+    assert not cache.has_key('test')
+
 def test_has_key_multicache():
     cache = Cache('test', data_dir='./cache', url=mc_url, type='ext:memcached')
     o = object()