[Checkins] SVN: Products.CMFCore/trunk/Products/CMFCore/ - FSObject: Ensure that ZCache invalidations only happens if the

Jens Vagelpohl jens at dataflake.org
Tue May 12 14:35:37 EDT 2009


Log message for revision 99882:
  - FSObject: Ensure that ZCache invalidations only happens if the
    filesystem modification time differs from the internally stored
    previous modification time.
    (https://bugs.launchpad.net/zope-cmf/+bug/325246)
  

Changed:
  U   Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
  U   Products.CMFCore/trunk/Products/CMFCore/FSFile.py
  U   Products.CMFCore/trunk/Products/CMFCore/FSImage.py
  U   Products.CMFCore/trunk/Products/CMFCore/FSObject.py
  U   Products.CMFCore/trunk/Products/CMFCore/tests/test_FSFile.py
  U   Products.CMFCore/trunk/Products/CMFCore/tests/test_FSImage.py

-=-
Modified: Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt	2009-05-12 16:44:05 UTC (rev 99881)
+++ Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt	2009-05-12 18:35:37 UTC (rev 99882)
@@ -4,6 +4,11 @@
 2.2.0 (unreleased)
 ------------------
 
+- FSObject: Ensure that ZCache invalidations only happens if the 
+  filesystem modification time differs from the internally stored
+  previous modification time.
+  (https://bugs.launchpad.net/zope-cmf/+bug/325246)
+
 - TypeInformation: DCWorkflow instances define a method and a guard 
   for vetoing object creation, but it was never used. Now  
   TypeInformation objects will consult these guard conditions during 

Modified: Products.CMFCore/trunk/Products/CMFCore/FSFile.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/FSFile.py	2009-05-12 16:44:05 UTC (rev 99881)
+++ Products.CMFCore/trunk/Products/CMFCore/FSFile.py	2009-05-12 18:35:37 UTC (rev 99882)
@@ -16,6 +16,7 @@
 """
 
 import codecs
+import os
 
 from AccessControl.SecurityInfo import ClassSecurityInfo
 from App.class_init import InitializeClass
@@ -98,7 +99,13 @@
             file.close()
 
         if reparse or self.content_type == 'unknown/unknown':
-            self.ZCacheable_invalidate()
+            try:
+                mtime = os.stat(self._filepath)[8]
+            except:
+                mtime = 0
+            if mtime != self._file_mod_time or mtime == 0:
+                self.ZCacheable_invalidate()
+                self._file_mod_time = mtime
             self.content_type=self._get_content_type(file, data, self.id)
         return data
 

Modified: Products.CMFCore/trunk/Products/CMFCore/FSImage.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/FSImage.py	2009-05-12 16:44:05 UTC (rev 99881)
+++ Products.CMFCore/trunk/Products/CMFCore/FSImage.py	2009-05-12 18:35:37 UTC (rev 99882)
@@ -15,6 +15,8 @@
 $Id$
 """
 
+import os
+
 from AccessControl.SecurityInfo import ClassSecurityInfo
 from App.class_init import InitializeClass
 from App.special_dtml import DTMLFile
@@ -72,7 +74,13 @@
             file.close()
 
         if reparse or self.content_type == 'unknown/unknown':
-            self.ZCacheable_invalidate()
+            try:
+                mtime = os.stat(self._filepath)[8]
+            except:
+                mtime = 0
+            if mtime != self._file_mod_time or mtime == 0:
+                self.ZCacheable_invalidate()
+                self._file_mod_time = mtime
             ct, width, height = getImageInfo( data )
             self.content_type = ct
             self.width = width

Modified: Products.CMFCore/trunk/Products/CMFCore/FSObject.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/FSObject.py	2009-05-12 16:44:05 UTC (rev 99881)
+++ Products.CMFCore/trunk/Products/CMFCore/FSObject.py	2009-05-12 18:35:37 UTC (rev 99882)
@@ -175,10 +175,10 @@
             except:
                 mtime = 0
             if not parsed or mtime != self._file_mod_time:
-                # if we have to read the file again, remove the cache
-                self.ZCacheable_invalidate()
                 self._readFile(1)
-                self._file_mod_time = mtime
+                if mtime != self._file_mod_time or mtime == 0:
+                    self.ZCacheable_invalidate()
+                    self._file_mod_time = mtime
                 self._parsed = 1
 
     security.declareProtected(View, 'get_size')

Modified: Products.CMFCore/trunk/Products/CMFCore/tests/test_FSFile.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/tests/test_FSFile.py	2009-05-12 16:44:05 UTC (rev 99881)
+++ Products.CMFCore/trunk/Products/CMFCore/tests/test_FSFile.py	2009-05-12 18:35:37 UTC (rev 99882)
@@ -233,7 +233,39 @@
         self.assertEqual(self.RESPONSE.getHeader('content-type'),
                          'application/x-javascript; charset=utf-8')
 
+    def test_unnecessary_invalidation_avoidance(self):
+        # See https://bugs.launchpad.net/zope-cmf/+bug/325246
+        invalidated = []
+        def fake_invalidate(*args, **kw):
+            invalidated.append(True)
+        file = self._makeOne( 'test_file', 'test_file.swf' )
+        file.ZCacheable_invalidate = fake_invalidate
 
+        # First pass: The internal file modification representation
+        # equals the filesystem modification time.
+        del invalidated[:]
+        file._readFile(True)
+        self.failIf(invalidated)
+
+        del invalidated[:]
+        file._parsed = False
+        file._updateFromFS()
+        self.failIf(invalidated)
+
+        # Second pass: Forcing a different internal file modification
+        # time onto the instance. Now the file will be invalidated.
+        del invalidated[:]
+        file._file_mod_time = 0
+        file._readFile(True)
+        self.failUnless(invalidated)
+
+        del invalidated[:]
+        file._file_mod_time = 0
+        file._parsed = False
+        file._updateFromFS()
+        self.failUnless(invalidated)
+
+
 def test_suite():
     return unittest.TestSuite((
         unittest.makeSuite(FSFileTests),

Modified: Products.CMFCore/trunk/Products/CMFCore/tests/test_FSImage.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/tests/test_FSImage.py	2009-05-12 16:44:05 UTC (rev 99881)
+++ Products.CMFCore/trunk/Products/CMFCore/tests/test_FSImage.py	2009-05-12 18:35:37 UTC (rev 99882)
@@ -234,7 +234,39 @@
         tag = image.tag()
         self.failUnless('alt=""' in tag)
 
+    def test_unnecessary_invalidation_avoidance(self):
+        # See https://bugs.launchpad.net/zope-cmf/+bug/325246
+        invalidated = []
+        def fake_invalidate(*args, **kw):
+            invalidated.append(True)
+        image = self._makeOne( 'test_image', 'test_image.gif' )
+        image.ZCacheable_invalidate = fake_invalidate
 
+        # First pass: The images internal file modification representation
+        # equals the filesystem modification time.
+        del invalidated[:]
+        image._readFile(True)
+        self.failIf(invalidated)
+
+        del invalidated[:]
+        image._parsed = False
+        image._updateFromFS()
+        self.failIf(invalidated)
+
+        # Second pass: Forcing a different internal file modification
+        # time onto the image instance. Now the image will be invalidated.
+        del invalidated[:]
+        image._file_mod_time = 0
+        image._readFile(True)
+        self.failUnless(invalidated)
+
+        del invalidated[:]
+        image._file_mod_time = 0
+        image._parsed = False
+        image._updateFromFS()
+        self.failUnless(invalidated)
+
+
 def test_suite():
     return unittest.TestSuite((
         unittest.makeSuite(FSImageTests),



More information about the Checkins mailing list