Mercurial > piecrust2
comparison piecrust/environment.py @ 47:558e3602be40
Cache rendered segments to disk.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 22 Aug 2014 12:25:35 -0700 |
parents | 43091c9837bf |
children | fce061f8c2ed |
comparison
equal
deleted
inserted
replaced
46:99dea56238af | 47:558e3602be40 |
---|---|
1 import re | |
1 import time | 2 import time |
3 import json | |
2 import logging | 4 import logging |
3 import threading | 5 import threading |
4 import repoze.lru | 6 import repoze.lru |
5 | 7 |
6 | 8 |
7 logger = logging.getLogger(__name__) | 9 logger = logging.getLogger(__name__) |
8 | 10 |
9 | 11 |
12 re_fs_cache_key = re.compile(r'[^\d\w\-\._]+') | |
13 | |
14 | |
15 def _make_fs_cache_key(key): | |
16 return re_fs_cache_key.sub('_', key) | |
17 | |
18 | |
10 class MemCache(object): | 19 class MemCache(object): |
20 """ Simple memory cache. It can be backed by a simple file-system | |
21 cache, but items need to be JSON-serializable to do this. | |
22 """ | |
11 def __init__(self, size=2048): | 23 def __init__(self, size=2048): |
12 self.cache = repoze.lru.LRUCache(size) | 24 self.cache = repoze.lru.LRUCache(size) |
13 self.lock = threading.RLock() | 25 self.lock = threading.RLock() |
26 self.fs_cache = None | |
14 | 27 |
15 def get(self, key, item_maker): | 28 def get(self, key, item_maker): |
16 item = self.cache.get(key) | 29 item = self.cache.get(key) |
17 if item is None: | 30 if item is None: |
18 logger.debug("Acquiring lock for: %s" % key) | 31 logger.debug("Acquiring lock for: %s" % key) |
19 with self.lock: | 32 with self.lock: |
20 item = self.cache.get(key) | 33 item = self.cache.get(key) |
21 if item is None: | 34 if item is None: |
35 if self.fs_cache is not None: | |
36 # Try first from the file-system cache. | |
37 fs_key = _make_fs_cache_key(key) | |
38 logger.debug("'%s' not found in cache, trying the " | |
39 "file-system: %s" % (key, fs_key)) | |
40 try: | |
41 item_raw = self.fs_cache.read(fs_key) | |
42 item = json.loads(item_raw) | |
43 self.cache.put(key, item) | |
44 return item | |
45 except: | |
46 pass | |
47 | |
48 # Look into the mem-cache. | |
22 logger.debug("'%s' not found in cache, must build." % key) | 49 logger.debug("'%s' not found in cache, must build." % key) |
23 item = item_maker() | 50 item = item_maker() |
24 self.cache.put(key, item) | 51 self.cache.put(key, item) |
52 | |
53 # Save to the file-system if needed. | |
54 if self.fs_cache is not None: | |
55 item_raw = json.dumps(item) | |
56 self.fs_cache.write(fs_key, item_raw) | |
25 return item | 57 return item |
26 | 58 |
27 | 59 |
28 PHASE_PAGE_PARSING = 0 | 60 PHASE_PAGE_PARSING = 0 |
29 PHASE_PAGE_FORMATTING = 1 | 61 PHASE_PAGE_FORMATTING = 1 |
74 self.page_repository = MemCache() | 106 self.page_repository = MemCache() |
75 self.rendered_segments_repository = MemCache() | 107 self.rendered_segments_repository = MemCache() |
76 self.base_asset_url_format = '%uri%' | 108 self.base_asset_url_format = '%uri%' |
77 | 109 |
78 def initialize(self, app): | 110 def initialize(self, app): |
79 pass | 111 cache = app.cache.getCache('renders') |
112 self.rendered_segments_repository.fs_cache = cache | |
80 | 113 |
81 | 114 |
82 class StandardEnvironment(Environment): | 115 class StandardEnvironment(Environment): |
83 def __init__(self): | 116 def __init__(self): |
84 super(StandardEnvironment, self).__init__() | 117 super(StandardEnvironment, self).__init__() |