changeset:   4207:0009178b69ef
branch:      docbook
tag:         tip
user:        matthijs@stdin.nl
date:        Wed Dec 03 10:39:22 2008 +0100
summary:     docbook parser: Use only a single cache entry.

diff -r 0274b9f1343b -r 0009178b69ef MoinMoin/parser/text_docbook.py
--- a/MoinMoin/parser/text_docbook.py	Mon Nov 24 22:40:14 2008 +0100
+++ b/MoinMoin/parser/text_docbook.py	Wed Dec 03 10:39:22 2008 +0100
@@ -67,24 +67,17 @@
         # speed up rendering. We have a separate entry for the filename,
         # so we can properly refresh the cache when the docbook_xsl
         # configuration value changes.
-        self.cached = caching.CacheEntry(self.request, 
-                                    arena='docbook',
-                                    key='compiled_xsl',
-                                    scope='farm',
-                                    use_pickle=True)
-
-        self.cached_name = caching.CacheEntry(self.request, 
-                                    arena='docbook',
-                                    key='docbook_xsl_filename',
-                                    scope='farm',
-                                    use_pickle=True)
-        
+        self.cached_xsl = caching.CacheEntry(self.request, 
+                                             arena='docbook',
+                                             key='compiled_xsl',
+                                             scope='farm',
+                                             use_pickle=True)
 
     def format(self, formatter):
         self.wikiParser.formatter = formatter
         XsltParser.format(self, formatter)
 
-    def get_cached_stylesheet(self, abs_db_xsl, log=True):
+    def get_cached_stylesheet(self, abs_db_xsl, timestamp):
         """ Try to get the compiled xsl file from the cache.
             
         @param abs_db_xsl: The input xsl file of which we should find
@@ -92,25 +85,27 @@
         @param errors: Should we do logging?
         """
         try:
-            if self.cached_name.content() != abs_db_xsl:
-                if log:
-                    logging.debug(
-                        "Docbook XSL file configuration changed from %s to %s" % 
-                        (cached_name.content(), abs_db_xsl)
-                    )
-            elif self.cached.needsUpdate(abs_db_xsl):
-                if log:
-                    logging.debug("Docbook XSL file changed")
-            else:
-                # Good, we got a cache hit!
-                compiled = self.cached.content()
-                if log:
-                    logging.debug("Got compiled Docbook XSL file from cache")
-                return compiled
+            (cfilename, ctimestamp, compiled) = self.cached_xsl.content()
         except caching.CacheError:
-            if log:
-                logging.debug("Got cache error for compiled XSL file")
-        return None
+            logging.debug("Got cache error for compiled XSL file")
+            return None
+    
+        if (abs_db_xsl != cfilename):
+            logging.debug(
+                "Docbook XSL file configuration changed from %s to %s" % 
+                (cfilename, abs_db_xsl)
+            )
+            return None
+
+        if (timestamp != ctimestamp):
+            # Note that this check is only partially sufficient, since
+            # the xsl typically includes a bunch of other files as well.
+            logging.debug("Docbook XSL file changed")
+            return None
+
+        # Good, we got a cache hit!
+        logging.debug("Got compiled Docbook XSL file from cache")
+        return compiled
 
     def append_stylesheet(self):
         """"
@@ -118,32 +113,27 @@
         """
         abs_db_xsl = os.path.abspath(self.db_xsl)
 
-        compiled = self.get_cached_stylesheet(abs_db_xsl)
+        try:
+            timestamp = os.path.getmtime(abs_db_xsl)
+            compiled = self.get_cached_stylesheet(abs_db_xsl, timestamp)
+        except os.error:
+            logging.warning(
+                "Couldn't get mtime of Docbook XSL file: '%s'" %
+                (abs_db_xsl)
+            )
+            timestamp = 0
+            compiled = None
 
         if compiled is None:
             # Recompile the XSL file
-            logging.debug("(Re)compiling Docbook XSL file: '%s'" % (abs_db_xsl))
+            logging.debug(
+                "(Re)compiling Docbook XSL file: '%s'" %
+                (abs_db_xsl)
+            )
             compiled = _compile_xsl(abs_db_xsl)
-            # Check the cache again (another thread might have filled
-            # the cache by now) and update the cache if that's not the
-            # case. Don't do any logging of the result, since that might
-            # be confusing.
-            if (self.get_cached_stylesheet(abs_db_xsl, log=False) is None):
-                # We first remove the old cached_name, to prevent an
-                # inconsistent situation and invalid cache hits after
-                # changing the xsl filename configuration. This does
-                # allow for possibly indefinite recompiling, if
-                # everytime a new thread triggers recompilation just
-                # between the remove and update of cached_name. However,
-                # the recheck of the cache combined with the long time
-                # needed to compile the xsl should make this case
-                # extremely unlikely.
-                self.cached_name.remove()
-                self.cached.update(compiled)
-                self.cached_name.update(abs_db_xsl)
-                logging.debug("Saved compiled Docbook XSL file to cache")
-            else:
-                logging.debug("Skipping saving of compiled Docbook XSL file to cache")
+            # Save compiled file to cache
+            self.cached_xsl.update((abs_db_xsl, timestamp, compiled))
+            logging.debug("Saved compiled Docbook XSL file to cache")
 
         self.processor.appendStylesheetInstance(compiled)
 
@@ -243,11 +233,7 @@
     # Append Stylesheet
     db_processor.appendStylesheet(sty_isrc)
 
-    # Pickled stylesheet will be self.abs_db_compiled_xsl file
-    db_root = db_processor.stylesheet.root
-
-    return db_root
-
+    return db_processor.stylesheet.root
 
 def _splitResult(iterator, result):
     startpos = 0

