# HG changeset patch # User Ludovic Chabant # Date 1409843619 25200 # Node ID e771c202583a74191b0771f1530e79451b68059d # Parent a643b14a59a3d3125351cfc654b3c8687fe2dba2 Fixes to the `cache` Jinja tag. * Thread safety, since it stores common data potentially coming from pages baked at the same time. * Correctly capture and restore modifications made to the execution context (e.g. sources used in the captured section). diff -r a643b14a59a3 -r e771c202583a piecrust/templating/jinjaengine.py --- a/piecrust/templating/jinjaengine.py Thu Sep 04 08:11:28 2014 -0700 +++ b/piecrust/templating/jinjaengine.py Thu Sep 04 08:13:39 2014 -0700 @@ -1,6 +1,7 @@ import re import time import logging +import threading import strict_rfc3339 from jinja2 import Environment, FileSystemLoader, TemplateNotFound from jinja2.exceptions import TemplateSyntaxError @@ -272,6 +273,7 @@ def __init__(self, environment): super(PieCrustCacheExtension, self).__init__(environment) + self._lock = threading.RLock() environment.extend( piecrust_cache_prefix='', @@ -301,15 +303,29 @@ def _cache_support(self, name, caller): key = self.environment.piecrust_cache_prefix + name + exc_stack = self.environment.app.env.exec_info_stack + render_ctx = exc_stack.current_page_info.render_ctx + # try to load the block from the cache # if there is no fragment in the cache, render it and store # it in the cache. - rv = self.environment.piecrust_cache.get(key) - if rv is not None: + pair = self.environment.piecrust_cache.get(key) + if pair is not None: + render_ctx.used_source_names.update(pair[1]) + return pair[0] + + with self._lock: + pair = self.environment.piecrust_cache.get(key) + if pair is not None: + render_ctx.used_source_names.update(pair[1]) + return pair[0] + + prev_used = render_ctx.used_source_names.copy() + rv = caller() + after_used = render_ctx.used_source_names.copy() + used_delta = after_used.difference(prev_used) + self.environment.piecrust_cache[key] = (rv, used_delta) return rv - rv = caller() - self.environment.piecrust_cache[key] = rv - return rv class PieCrustSpacelessExtension(HtmlCompressor):