Mercurial > piecrust2
changeset 47:558e3602be40
Cache rendered segments to disk.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 22 Aug 2014 12:25:35 -0700 |
parents | 99dea56238af |
children | 002fa58f54dc |
files | piecrust/environment.py |
diffstat | 1 files changed, 34 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/piecrust/environment.py Thu Aug 21 23:26:44 2014 -0700 +++ b/piecrust/environment.py Fri Aug 22 12:25:35 2014 -0700 @@ -1,4 +1,6 @@ +import re import time +import json import logging import threading import repoze.lru @@ -7,10 +9,21 @@ logger = logging.getLogger(__name__) +re_fs_cache_key = re.compile(r'[^\d\w\-\._]+') + + +def _make_fs_cache_key(key): + return re_fs_cache_key.sub('_', key) + + class MemCache(object): + """ Simple memory cache. It can be backed by a simple file-system + cache, but items need to be JSON-serializable to do this. + """ def __init__(self, size=2048): self.cache = repoze.lru.LRUCache(size) self.lock = threading.RLock() + self.fs_cache = None def get(self, key, item_maker): item = self.cache.get(key) @@ -19,9 +32,28 @@ with self.lock: item = self.cache.get(key) if item is None: + if self.fs_cache is not None: + # Try first from the file-system cache. + fs_key = _make_fs_cache_key(key) + logger.debug("'%s' not found in cache, trying the " + "file-system: %s" % (key, fs_key)) + try: + item_raw = self.fs_cache.read(fs_key) + item = json.loads(item_raw) + self.cache.put(key, item) + return item + except: + pass + + # Look into the mem-cache. logger.debug("'%s' not found in cache, must build." % key) item = item_maker() self.cache.put(key, item) + + # Save to the file-system if needed. + if self.fs_cache is not None: + item_raw = json.dumps(item) + self.fs_cache.write(fs_key, item_raw) return item @@ -76,7 +108,8 @@ self.base_asset_url_format = '%uri%' def initialize(self, app): - pass + cache = app.cache.getCache('renders') + self.rendered_segments_repository.fs_cache = cache class StandardEnvironment(Environment):