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..3e76b477af1f117894d7aaa10ab8560a24ba413a 100644 |
| --- a/appengine/findit/common/cache_decorator.py |
| +++ b/appengine/findit/common/cache_decorator.py |
| @@ -39,11 +39,15 @@ 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('~'), '.cache') |
|
Martin Barbella
2016/10/26 23:21:20
This shouldn't use such a generic name. This will
wrengr
2016/10/27 16:36:47
Seconded.
Sharu Jiang
2016/10/27 21:59:05
Done. Use .culprit_finder/local_cache since it's s
|
| + |
| class Cacher(object): |
|
wrengr
2016/10/27 16:36:47
Using "-er" names for classes is weird. Why not ju
Sharu Jiang
2016/10/27 21:59:05
I think it means 'Cacher' caches.
wrengr
2016/10/28 18:02:00
In all the communities I've programmed in, we don'
Sharu Jiang
2016/11/08 01:17:12
This make senses, added a todo.
|
| """An interface to cache and retrieve data. |
| @@ -133,6 +137,38 @@ class CompressedMemCacher(Cacher): |
| return len(keys_not_set) == 0 |
| +class LocalCacher(object): |
|
Martin Barbella
2016/10/26 23:21:20
Solely for the sake of consistency, it seems like
Sharu Jiang
2016/10/27 21:59:05
Oops, it should.
|
| + """Cacher that uses local files to cache data.""" |
| + |
| + lock = threading.Lock() |
| + |
| + def __init__(self, cache_dir=_DEFAULT_LOCAL_CACHE_DIR): |
| + self.cache_dir = cache_dir |
| + if not os.path.exists(cache_dir): # pragma: no cover. |
| + os.mkdir(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: # pragma: no cover. |
| + logging.error('Failed load cache.') |
|
Martin Barbella
2016/10/26 23:21:20
Could you make this error a bit more descriptive,
Sharu Jiang
2016/10/27 21:59:05
Done.
|
| + 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: # pragma: no cover. |
| + logging.error('Failed to cache key %s', key) |
| + |
| + |
| def _DefaultKeyGenerator(func, args, kwargs): |
| """Generates a key from the function and arguments passed to it. |