Commits

Mike Bayer committed e291674

* file-based cache will not hold onto cached value once read from file;
will create new value if the file is deleted as opposed to re-using
what was last read. This allows external removal of files to be
used as a cache-invalidation mechanism.

Comments (0)

Files changed (3)

 Beaker Changelog
 ================
-
+1.0.4
+* file-based cache will not hold onto cached value once read from file;
+  will create new value if the file is deleted as opposed to re-using
+  what was last read.  This allows external removal of files to be
+  used as a cache-invalidation mechanism.
+  
 1.0.3 (10/14/2008)
 * Fixed os.getpid issue on GAE.
 * CookieSession will add '_expires' value to data when an expire time is set, 

beaker/container.py

         return self.has_current_value() or self.createfunc is not None  
 
     def has_current_value(self):
-        return self.has_value() and not self.is_expired()
+        self.namespacemanager.acquire_read_lock()
+        try:    
+            has_value = self.namespacemanager.has_key(self.key)
+            if has_value:
+                [self.storedtime, value] = self.namespacemanager[self.key]
+                return not self._is_expired()
+            else:
+                return False
+        finally:
+            self.namespacemanager.release_read_lock()
 
-    def is_expired(self):
-        """Return true if this container's value is expired."""
-
+    def _is_expired(self):
+        """Return true if this container's value is expired.
+        
+        Note that this method is only correct if has_current_value()
+        or get_value() have been called already.
+        
+        """
         return (
             (
                 self.starttime is not None and
             has_value = self.has_value()
             if has_value:
                 [self.storedtime, value] = self.namespacemanager[self.key]
-                if not self.is_expired():
+                if not self._is_expired():
                     return value
 
-            if not self.can_have_value():
+            if not self.createfunc:
                 raise KeyError(self.key)
         finally:
             self.namespacemanager.release_read_lock()
             try:
                 if self.has_value():
                     [self.storedtime, value] = self.namespacemanager[self.key]
-                    if not self.is_expired():
+                    if not self._is_expired():
                         return value
             finally:
                 self.namespacemanager.release_read_lock()
             except (IOError, OSError, EOFError, cPickle.PickleError):
                 pass
             fh.close()
+
         self.flags = flags
         
     def do_close(self):
             cPickle.dump(self.hash, fh)
             fh.close()
 
+        self.hash = {}
         self.flags = None
                 
     def do_remove(self):

tests/test_container.py

         assert False
     except:
         pass
+
+
+def test_removing_file_refreshes():
+    """test that the cache doesn't ignore file removals"""
+    
+    x = [0]
+    def create():
+        x[0] += 1
+        return x[0]
+        
+    value = Value('test', context, 'refresh_test', clsmap['file'], data_dir='./cache', createfunc=create, starttime=time.time())
+    assert value.get_value() == 1
+    assert value.get_value() == 1
+    os.remove(value.namespacemanager.file)
+    assert value.get_value() == 2
+    
+    
+    
+