Mercurial > piecrust2
changeset 89:e771c202583a
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).
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 04 Sep 2014 08:13:39 -0700 |
parents | a643b14a59a3 |
children | e293f08d954e |
files | piecrust/templating/jinjaengine.py |
diffstat | 1 files changed, 21 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- 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):