Mercurial > piecrust2
comparison piecrust/environment.py @ 96:0445a2232de7
Improvements and fixes to incremental baking.
* Better handling of the render pass during page rendering.
* Used sources are paired with the pass they were used in.
* Proper use and invalidation of the rendered segments cache based on render
passes.
* The `Assetor` is also better tracking what was used in a page.
* Add flags on a page to get better caching information for the debug window.
* Property invalidation of the previous bake record when needed.
* Better information about why pages are delayed.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 07 Sep 2014 23:48:57 -0700 |
parents | 563ce5dd02af |
children | 208c652551a3 |
comparison
equal
deleted
inserted
replaced
95:cb6eadea0845 | 96:0445a2232de7 |
---|---|
23 """ | 23 """ |
24 def __init__(self, size=2048): | 24 def __init__(self, size=2048): |
25 self.cache = repoze.lru.LRUCache(size) | 25 self.cache = repoze.lru.LRUCache(size) |
26 self.lock = threading.RLock() | 26 self.lock = threading.RLock() |
27 self.fs_cache = None | 27 self.fs_cache = None |
28 self._invalidated_fs_items = set() | |
29 | |
30 def invalidate(self, key): | |
31 with self.lock: | |
32 logger.debug("Invalidating cache item '%s'." % key) | |
33 self.cache.invalidate(key) | |
34 if self.fs_cache: | |
35 logger.debug("Invalidating FS cache item '%s'." % key) | |
36 fs_key = _make_fs_cache_key(key) | |
37 self._invalidated_fs_items.add(fs_key) | |
28 | 38 |
29 def get(self, key, item_maker, fs_cache_time=None): | 39 def get(self, key, item_maker, fs_cache_time=None): |
30 item = self.cache.get(key) | 40 item = self.cache.get(key) |
31 if item is None: | 41 if item is None: |
32 logger.debug("Acquiring lock for: %s" % key) | 42 logger.debug("Acquiring lock for: %s" % key) |
35 if item is None: | 45 if item is None: |
36 if (self.fs_cache is not None and | 46 if (self.fs_cache is not None and |
37 fs_cache_time is not None): | 47 fs_cache_time is not None): |
38 # Try first from the file-system cache. | 48 # Try first from the file-system cache. |
39 fs_key = _make_fs_cache_key(key) | 49 fs_key = _make_fs_cache_key(key) |
40 if self.fs_cache.isValid(fs_key, fs_cache_time): | 50 if (fs_key not in self._invalidated_fs_items and |
51 self.fs_cache.isValid(fs_key, fs_cache_time)): | |
41 logger.debug("'%s' found in file-system cache." % | 52 logger.debug("'%s' found in file-system cache." % |
42 key) | 53 key) |
43 item_raw = self.fs_cache.read(fs_key) | 54 item_raw = self.fs_cache.read(fs_key) |
44 item = json.loads(item_raw, | 55 item = json.loads(item_raw, |
45 object_pairs_hook=collections.OrderedDict) | 56 object_pairs_hook=collections.OrderedDict) |
57 item_raw = json.dumps(item) | 68 item_raw = json.dumps(item) |
58 self.fs_cache.write(fs_key, item_raw) | 69 self.fs_cache.write(fs_key, item_raw) |
59 return item | 70 return item |
60 | 71 |
61 | 72 |
62 PHASE_PAGE_PARSING = 0 | |
63 PHASE_PAGE_FORMATTING = 1 | |
64 PHASE_PAGE_RENDERING = 2 | |
65 | |
66 | |
67 class ExecutionInfo(object): | 73 class ExecutionInfo(object): |
68 def __init__(self, page, phase, render_ctx): | 74 def __init__(self, page, render_ctx): |
69 self.page = page | 75 self.page = page |
70 self.phase = phase | |
71 self.render_ctx = render_ctx | 76 self.render_ctx = render_ctx |
72 self.was_cache_valid = False | 77 self.was_cache_valid = False |
73 self.start_time = time.clock() | 78 self.start_time = time.clock() |
74 | 79 |
75 | 80 |
91 for ei in self._page_stack: | 96 for ei in self._page_stack: |
92 if ei.page == page: | 97 if ei.page == page: |
93 return True | 98 return True |
94 return False | 99 return False |
95 | 100 |
96 def pushPage(self, page, phase, render_ctx): | 101 def pushPage(self, page, render_ctx): |
97 self._page_stack.append(ExecutionInfo(page, phase, render_ctx)) | 102 if len(self._page_stack) > 0: |
103 top = self._page_stack[-1] | |
104 assert top.page is not page | |
105 self._page_stack.append(ExecutionInfo(page, render_ctx)) | |
98 | 106 |
99 def popPage(self): | 107 def popPage(self): |
100 del self._page_stack[-1] | 108 del self._page_stack[-1] |
101 | 109 |
102 | 110 |
106 self.exec_info_stack = ExecutionInfoStack() | 114 self.exec_info_stack = ExecutionInfoStack() |
107 self.was_cache_cleaned = False | 115 self.was_cache_cleaned = False |
108 self.page_repository = MemCache() | 116 self.page_repository = MemCache() |
109 self.rendered_segments_repository = MemCache() | 117 self.rendered_segments_repository = MemCache() |
110 self.base_asset_url_format = '%uri%' | 118 self.base_asset_url_format = '%uri%' |
111 self._use_rendered_segments_fs_cache = False | |
112 | 119 |
113 def initialize(self, app): | 120 def initialize(self, app): |
114 if self._use_rendered_segments_fs_cache: | 121 cache = app.cache.getCache('renders') |
115 cache = app.cache.getCache('renders') | 122 self.rendered_segments_repository.fs_cache = cache |
116 self.rendered_segments_repository.fs_cache = cache | |
117 | 123 |
118 | 124 |
119 class StandardEnvironment(Environment): | 125 class StandardEnvironment(Environment): |
120 def __init__(self): | 126 def __init__(self): |
121 super(StandardEnvironment, self).__init__() | 127 super(StandardEnvironment, self).__init__() |