Chromium Code Reviews| Index: appengine/findit/common/cache_decorator.py |
| diff --git a/appengine/findit/common/cache_decorator.py b/appengine/findit/common/cache_decorator.py |
| index 6f1bb1efe42dc866aa7841e4df8eb84db698f26f..9fd67867a42f9af66301c415d1983f6ec9da27fa 100644 |
| --- a/appengine/findit/common/cache_decorator.py |
| +++ b/appengine/findit/common/cache_decorator.py |
| @@ -39,11 +39,16 @@ import functools |
| import hashlib |
| import inspect |
| import logging |
| +import os |
| import pickle |
| +import threading |
| import zlib |
| from google.appengine.api import memcache |
| +_DEFAULT_LOCAL_CACHE_DIR = os.path.join(os.path.expanduser('~'), |
| + '.culprit_finder', 'local_cache') |
| + |
| class Cacher(object): |
| """An interface to cache and retrieve data. |
| @@ -133,6 +138,38 @@ class CompressedMemCacher(Cacher): |
| return len(keys_not_set) == 0 |
| +class LocalCacher(Cacher): |
| + """Cacher that uses local files to cache data.""" |
| + |
| + lock = threading.Lock() |
| + |
| + def __init__(self, cache_dir=_DEFAULT_LOCAL_CACHE_DIR): |
|
stgao
2016/11/02 02:15:07
Can we avoid the default value, and let client pas
Sharu Jiang
2016/11/08 01:17:12
Done.
|
| + self.cache_dir = cache_dir |
| + if not os.path.exists(cache_dir): # pragma: no cover. |
| + os.makedirs(cache_dir) |
| + |
| + def Get(self, key): |
| + with LocalCacher.lock: |
| + path = os.path.join(self.cache_dir, key) |
| + if not os.path.exists(path): |
| + return None |
| + |
| + try: |
| + with open(path) as f: |
| + return pickle.loads(zlib.decompress(f.read())) |
| + except Exception as e: # pragma: no cover. |
| + logging.error('Failed loading cache: %s', e) |
| + return None |
| + |
| + def Set(self, key, data): # pylint: disable=W |
| + with LocalCacher.lock: |
| + try: |
| + with open(os.path.join(self.cache_dir, key), 'wb') as f: |
| + f.write(zlib.compress(pickle.dumps(data))) |
| + except Exception as e: # pragma: no cover. |
| + logging.error('Failed setting cache for key %s: %s', key, e) |
| + |
| + |
| def _DefaultKeyGenerator(func, args, kwargs): |
| """Generates a key from the function and arguments passed to it. |