Mercurial > piecrust2
comparison piecrust/environment.py @ 114:371a6c879ab9
When possible, try and batch-load pages so we only lock once.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 19 Oct 2014 00:33:28 -0700 |
parents | 208c652551a3 |
children | 1187739e5a19 |
comparison
equal
deleted
inserted
replaced
113:de257cc40ce1 | 114:371a6c879ab9 |
---|---|
1 import re | 1 import re |
2 import time | 2 import time |
3 import json | 3 import json |
4 import logging | 4 import logging |
5 import threading | 5 import threading |
6 import contextlib | |
6 import collections | 7 import collections |
7 import repoze.lru | 8 import repoze.lru |
8 | 9 |
9 | 10 |
10 logger = logging.getLogger(__name__) | 11 logger = logging.getLogger(__name__) |
21 """ Simple memory cache. It can be backed by a simple file-system | 22 """ Simple memory cache. It can be backed by a simple file-system |
22 cache, but items need to be JSON-serializable to do this. | 23 cache, but items need to be JSON-serializable to do this. |
23 """ | 24 """ |
24 def __init__(self, size=2048): | 25 def __init__(self, size=2048): |
25 self.cache = repoze.lru.LRUCache(size) | 26 self.cache = repoze.lru.LRUCache(size) |
26 self.lock = threading.RLock() | |
27 self.fs_cache = None | 27 self.fs_cache = None |
28 self._invalidated_fs_items = set() | 28 self._invalidated_fs_items = set() |
29 self._lock = threading.RLock() | |
30 | |
31 @contextlib.contextmanager | |
32 def startBatchGet(self): | |
33 logger.debug("Starting batch cache operation.") | |
34 with self._lock: | |
35 yield | |
36 logger.debug("Ending batch cache operation.") | |
29 | 37 |
30 def invalidate(self, key): | 38 def invalidate(self, key): |
31 with self.lock: | 39 with self._lock: |
32 logger.debug("Invalidating cache item '%s'." % key) | 40 logger.debug("Invalidating cache item '%s'." % key) |
33 self.cache.invalidate(key) | 41 self.cache.invalidate(key) |
34 if self.fs_cache: | 42 if self.fs_cache: |
35 logger.debug("Invalidating FS cache item '%s'." % key) | 43 logger.debug("Invalidating FS cache item '%s'." % key) |
36 fs_key = _make_fs_cache_key(key) | 44 fs_key = _make_fs_cache_key(key) |
38 | 46 |
39 def get(self, key, item_maker, fs_cache_time=None): | 47 def get(self, key, item_maker, fs_cache_time=None): |
40 item = self.cache.get(key) | 48 item = self.cache.get(key) |
41 if item is None: | 49 if item is None: |
42 logger.debug("Acquiring lock for: %s" % key) | 50 logger.debug("Acquiring lock for: %s" % key) |
43 with self.lock: | 51 with self._lock: |
44 item = self.cache.get(key) | 52 item = self.cache.get(key) |
45 if item is None: | 53 if item is None: |
46 if (self.fs_cache is not None and | 54 if (self.fs_cache is not None and |
47 fs_cache_time is not None): | 55 fs_cache_time is not None): |
48 # Try first from the file-system cache. | 56 # Try first from the file-system cache. |
105 self._page_stack.append(ExecutionInfo(page, render_ctx)) | 113 self._page_stack.append(ExecutionInfo(page, render_ctx)) |
106 | 114 |
107 def popPage(self): | 115 def popPage(self): |
108 del self._page_stack[-1] | 116 del self._page_stack[-1] |
109 | 117 |
118 def clear(self): | |
119 self._page_stack = [] | |
120 | |
110 | 121 |
111 class Environment(object): | 122 class Environment(object): |
112 def __init__(self): | 123 def __init__(self): |
113 self.start_time = time.clock() | 124 self.start_time = None |
114 self.exec_info_stack = ExecutionInfoStack() | 125 self.exec_info_stack = ExecutionInfoStack() |
115 self.was_cache_cleaned = False | 126 self.was_cache_cleaned = False |
127 self.base_asset_url_format = '%uri%' | |
116 self.page_repository = MemCache() | 128 self.page_repository = MemCache() |
117 self.rendered_segments_repository = MemCache() | 129 self.rendered_segments_repository = MemCache() |
118 self.fs_caches = { | 130 self.fs_caches = { |
119 'renders': self.rendered_segments_repository} | 131 'renders': self.rendered_segments_repository} |
132 | |
133 def initialize(self, app): | |
134 self.start_time = time.clock() | |
135 self.exec_info_stack.clear() | |
136 self.was_cache_cleaned = False | |
120 self.base_asset_url_format = '%uri%' | 137 self.base_asset_url_format = '%uri%' |
121 | 138 |
122 def initialize(self, app): | |
123 for name, repo in self.fs_caches.items(): | 139 for name, repo in self.fs_caches.items(): |
124 cache = app.cache.getCache(name) | 140 cache = app.cache.getCache(name) |
125 repo.fs_cache = cache | 141 repo.fs_cache = cache |
126 | 142 |
127 | 143 |