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