Mercurial > piecrust2
comparison piecrust/templating/jinjaengine.py @ 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 | 071cc99b1779 |
children | 28444014ce7d |
comparison
equal
deleted
inserted
replaced
88:a643b14a59a3 | 89:e771c202583a |
---|---|
1 import re | 1 import re |
2 import time | 2 import time |
3 import logging | 3 import logging |
4 import threading | |
4 import strict_rfc3339 | 5 import strict_rfc3339 |
5 from jinja2 import Environment, FileSystemLoader, TemplateNotFound | 6 from jinja2 import Environment, FileSystemLoader, TemplateNotFound |
6 from jinja2.exceptions import TemplateSyntaxError | 7 from jinja2.exceptions import TemplateSyntaxError |
7 from jinja2.ext import Extension, Markup | 8 from jinja2.ext import Extension, Markup |
8 from jinja2.lexer import Token, describe_token | 9 from jinja2.lexer import Token, describe_token |
270 class PieCrustCacheExtension(Extension): | 271 class PieCrustCacheExtension(Extension): |
271 tags = set(['pccache', 'cache']) | 272 tags = set(['pccache', 'cache']) |
272 | 273 |
273 def __init__(self, environment): | 274 def __init__(self, environment): |
274 super(PieCrustCacheExtension, self).__init__(environment) | 275 super(PieCrustCacheExtension, self).__init__(environment) |
276 self._lock = threading.RLock() | |
275 | 277 |
276 environment.extend( | 278 environment.extend( |
277 piecrust_cache_prefix='', | 279 piecrust_cache_prefix='', |
278 piecrust_cache={} | 280 piecrust_cache={} |
279 ) | 281 ) |
299 [], [], body).set_lineno(lineno) | 301 [], [], body).set_lineno(lineno) |
300 | 302 |
301 def _cache_support(self, name, caller): | 303 def _cache_support(self, name, caller): |
302 key = self.environment.piecrust_cache_prefix + name | 304 key = self.environment.piecrust_cache_prefix + name |
303 | 305 |
306 exc_stack = self.environment.app.env.exec_info_stack | |
307 render_ctx = exc_stack.current_page_info.render_ctx | |
308 | |
304 # try to load the block from the cache | 309 # try to load the block from the cache |
305 # if there is no fragment in the cache, render it and store | 310 # if there is no fragment in the cache, render it and store |
306 # it in the cache. | 311 # it in the cache. |
307 rv = self.environment.piecrust_cache.get(key) | 312 pair = self.environment.piecrust_cache.get(key) |
308 if rv is not None: | 313 if pair is not None: |
314 render_ctx.used_source_names.update(pair[1]) | |
315 return pair[0] | |
316 | |
317 with self._lock: | |
318 pair = self.environment.piecrust_cache.get(key) | |
319 if pair is not None: | |
320 render_ctx.used_source_names.update(pair[1]) | |
321 return pair[0] | |
322 | |
323 prev_used = render_ctx.used_source_names.copy() | |
324 rv = caller() | |
325 after_used = render_ctx.used_source_names.copy() | |
326 used_delta = after_used.difference(prev_used) | |
327 self.environment.piecrust_cache[key] = (rv, used_delta) | |
309 return rv | 328 return rv |
310 rv = caller() | |
311 self.environment.piecrust_cache[key] = rv | |
312 return rv | |
313 | 329 |
314 | 330 |
315 class PieCrustSpacelessExtension(HtmlCompressor): | 331 class PieCrustSpacelessExtension(HtmlCompressor): |
316 """ A re-implementation of `SelectiveHtmlCompressor` so that we can | 332 """ A re-implementation of `SelectiveHtmlCompressor` so that we can |
317 both use `strip` or `spaceless` in templates. | 333 both use `strip` or `spaceless` in templates. |