Mercurial > piecrust2
annotate piecrust/cache.py @ 894:ca357249a321
admin: Read an optional Flask-app configuration file.
| author | Ludovic Chabant <ludovic@chabant.com> |
|---|---|
| date | Sun, 02 Jul 2017 22:21:24 -0700 |
| parents | d1095774bfcf |
| children | f2b75e4be981 |
| rev | line source |
|---|---|
| 0 | 1 import os |
| 2 import os.path | |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
3 import json |
|
371
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
4 import shutil |
| 0 | 5 import codecs |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
6 import hashlib |
|
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
7 import logging |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
8 import repoze.lru |
|
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
9 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
10 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
11 logger = logging.getLogger(__name__) |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
12 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
13 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
14 class ExtensibleCache(object): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
15 def __init__(self, base_dir): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
16 self.base_dir = base_dir |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
17 self.caches = {} |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
18 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
19 @property |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
20 def enabled(self): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
21 return True |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
22 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
23 def getCache(self, name): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
24 c = self.caches.get(name) |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
25 if c is None: |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
26 c_dir = os.path.join(self.base_dir, name) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
27 if not os.path.isdir(c_dir): |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
28 os.makedirs(c_dir, 0o755) |
|
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
29 |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
30 c = SimpleCache(c_dir) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
31 self.caches[name] = c |
|
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
32 return c |
| 0 | 33 |
|
45
efd0d3bacc9e
Don't recursively clean the cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
34 def getCacheDir(self, name): |
|
efd0d3bacc9e
Don't recursively clean the cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
35 return os.path.join(self.base_dir, name) |
|
efd0d3bacc9e
Don't recursively clean the cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
36 |
|
105
7d2fdf43d7ca
Property clean all caches when force baking, except the `app` cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
45
diff
changeset
|
37 def getCacheNames(self, except_names=None): |
|
7d2fdf43d7ca
Property clean all caches when force baking, except the `app` cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
45
diff
changeset
|
38 _, dirnames, __ = next(os.walk(self.base_dir)) |
|
7d2fdf43d7ca
Property clean all caches when force baking, except the `app` cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
45
diff
changeset
|
39 if except_names is None: |
|
7d2fdf43d7ca
Property clean all caches when force baking, except the `app` cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
45
diff
changeset
|
40 return dirnames |
|
7d2fdf43d7ca
Property clean all caches when force baking, except the `app` cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
45
diff
changeset
|
41 return [dn for dn in dirnames if dn not in except_names] |
|
7d2fdf43d7ca
Property clean all caches when force baking, except the `app` cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
45
diff
changeset
|
42 |
|
371
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
43 def clearCache(self, name): |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
44 cache_dir = self.getCacheDir(name) |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
45 if os.path.isdir(cache_dir): |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
46 logger.debug("Cleaning cache: %s" % cache_dir) |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
47 shutil.rmtree(cache_dir) |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
48 |
|
424
5feb71d31a4f
internal: Fix caches being orphaned from their directory.
Ludovic Chabant <ludovic@chabant.com>
parents:
416
diff
changeset
|
49 # Re-create the cache-dir because now our Cache instance points |
|
5feb71d31a4f
internal: Fix caches being orphaned from their directory.
Ludovic Chabant <ludovic@chabant.com>
parents:
416
diff
changeset
|
50 # to a directory that doesn't exist anymore. |
|
5feb71d31a4f
internal: Fix caches being orphaned from their directory.
Ludovic Chabant <ludovic@chabant.com>
parents:
416
diff
changeset
|
51 os.makedirs(cache_dir, 0o755) |
|
5feb71d31a4f
internal: Fix caches being orphaned from their directory.
Ludovic Chabant <ludovic@chabant.com>
parents:
416
diff
changeset
|
52 |
|
371
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
53 def clearCaches(self, except_names=None): |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
54 for name in self.getCacheNames(except_names=except_names): |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
55 self.clearCache(name) |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
56 |
| 0 | 57 |
| 58 class SimpleCache(object): | |
| 59 def __init__(self, base_dir): | |
|
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
60 self.base_dir = base_dir |
| 0 | 61 if not os.path.isdir(base_dir): |
|
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
62 raise Exception("Cache directory doesn't exist: %s" % base_dir) |
| 0 | 63 |
| 64 def isValid(self, path, time): | |
| 65 cache_time = self.getCacheTime(path) | |
| 66 if cache_time is None: | |
| 67 return False | |
| 68 if isinstance(time, list): | |
| 69 for t in time: | |
| 70 if cache_time < t: | |
| 71 return False | |
| 72 return True | |
| 73 return cache_time >= time | |
| 74 | |
| 75 def getCacheTime(self, path): | |
| 76 cache_path = self.getCachePath(path) | |
| 77 try: | |
| 78 return os.path.getmtime(cache_path) | |
| 79 except os.error: | |
| 80 return None | |
| 81 | |
| 82 def has(self, path): | |
| 83 cache_path = self.getCachePath(path) | |
| 84 return os.path.isfile(cache_path) | |
| 85 | |
| 86 def read(self, path): | |
| 87 cache_path = self.getCachePath(path) | |
|
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
88 logger.debug("Reading cache: %s" % cache_path) |
| 0 | 89 with codecs.open(cache_path, 'r', 'utf-8') as fp: |
| 90 return fp.read() | |
| 91 | |
| 92 def write(self, path, content): | |
| 93 cache_path = self.getCachePath(path) | |
| 94 cache_dir = os.path.dirname(cache_path) | |
| 95 if not os.path.isdir(cache_dir): | |
| 5 | 96 os.makedirs(cache_dir, 0o755) |
|
45
efd0d3bacc9e
Don't recursively clean the cache.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
97 logger.debug("Writing cache: %s" % cache_path) |
| 0 | 98 with codecs.open(cache_path, 'w', 'utf-8') as fp: |
| 99 fp.write(content) | |
| 100 | |
|
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
101 def getCachePath(self, path): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
102 if path.startswith('.'): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
103 path = '__index__' + path |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
104 return os.path.join(self.base_dir, path) |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
105 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
106 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
107 class NullCache(object): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
108 def isValid(self, path, time): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
109 return False |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
110 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
111 def getCacheTime(self, path): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
112 return None |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
113 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
114 def has(self, path): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
115 return False |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
116 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
117 def read(self, path): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
118 raise Exception("Null cache has no data.") |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
119 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
120 def write(self, path, content): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
121 pass |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
122 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
123 def getCachePath(self, path): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
124 raise Exception("Null cache can't make paths.") |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
125 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
126 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
127 class NullExtensibleCache(object): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
128 def __init__(self): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
129 self.null_cache = NullCache() |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
130 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
131 @property |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
132 def enabled(self): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
133 return False |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
134 |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
135 def getCache(self, name): |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
136 return self.null_cache |
|
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
137 |
|
371
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
138 def getCacheDir(self, name): |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
139 raise NotImplementedError() |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
140 |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
141 def getCacheNames(self, except_names=None): |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
142 return [] |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
143 |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
144 def clearCache(self, name): |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
145 pass |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
146 |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
147 def clearCaches(self, except_names=None): |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
148 pass |
|
c2ca72fb7f0b
caching: Use separate caches for config variants and other contexts.
Ludovic Chabant <ludovic@chabant.com>
parents:
105
diff
changeset
|
149 |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
150 |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
151 def _make_fs_cache_key(key): |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
152 return hashlib.md5(key.encode('utf8')).hexdigest() |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
153 |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
154 |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
155 class MemCache(object): |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
156 """ Simple memory cache. It can be backed by a simple file-system |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
157 cache, but items need to be JSON-serializable to do this. |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
158 """ |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
159 def __init__(self, size=2048): |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
160 self.cache = repoze.lru.LRUCache(size) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
161 self.fs_cache = None |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
162 self._last_access_hit = None |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
163 self._invalidated_fs_items = set() |
|
687
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
164 self._missed_keys = [] |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
165 self._misses = 0 |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
166 self._hits = 0 |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
167 |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
168 @property |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
169 def last_access_hit(self): |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
170 return self._last_access_hit |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
171 |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
172 def invalidate(self, key): |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
173 logger.debug("Invalidating cache item '%s'." % key) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
174 self.cache.invalidate(key) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
175 if self.fs_cache: |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
176 logger.debug("Invalidating FS cache item '%s'." % key) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
177 fs_key = _make_fs_cache_key(key) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
178 self._invalidated_fs_items.add(fs_key) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
179 |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
180 def put(self, key, item, save_to_fs=True): |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
181 self.cache.put(key, item) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
182 if self.fs_cache and save_to_fs: |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
183 fs_key = _make_fs_cache_key(key) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
184 item_raw = json.dumps(item) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
185 self.fs_cache.write(fs_key, item_raw) |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
186 |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
187 def get(self, key, item_maker, fs_cache_time=None, save_to_fs=True): |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
188 self._last_access_hit = True |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
189 item = self.cache.get(key) |
|
687
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
190 if item is not None: |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
191 self._hits += 1 |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
192 return item |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
193 |
|
876
d1095774bfcf
refactor: Fix some issues with record/cache entry collisions, add counters.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
194 if self.fs_cache is not None: |
|
d1095774bfcf
refactor: Fix some issues with record/cache entry collisions, add counters.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
195 if fs_cache_time is None: |
|
d1095774bfcf
refactor: Fix some issues with record/cache entry collisions, add counters.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
196 raise ValueError( |
|
d1095774bfcf
refactor: Fix some issues with record/cache entry collisions, add counters.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
197 "No file-system cache time was given for '%s'. " |
|
d1095774bfcf
refactor: Fix some issues with record/cache entry collisions, add counters.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
198 "This would result in degraded performance." % key) |
|
d1095774bfcf
refactor: Fix some issues with record/cache entry collisions, add counters.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
199 |
|
687
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
200 # Try first from the file-system cache. |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
201 fs_key = _make_fs_cache_key(key) |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
202 if (fs_key not in self._invalidated_fs_items and |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
203 self.fs_cache.isValid(fs_key, fs_cache_time)): |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
204 logger.debug("'%s' found in file-system cache." % |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
205 key) |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
206 item_raw = self.fs_cache.read(fs_key) |
|
719
a066f4ac9094
rendering: Use `fastpickle` serialization before JSON.
Ludovic Chabant <ludovic@chabant.com>
parents:
687
diff
changeset
|
207 item = json.loads(item_raw) |
|
687
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
208 self.cache.put(key, item) |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
209 self._hits += 1 |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
210 return item |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
211 |
|
687
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
212 # Look into the mem-cache. |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
213 logger.debug("'%s' not found in cache, must build." % key) |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
214 item = item_maker() |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
215 self.cache.put(key, item) |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
216 self._last_access_hit = False |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
217 self._misses += 1 |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
218 self._missed_keys.append(key) |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
219 |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
220 # Save to the file-system if needed. |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
221 if self.fs_cache is not None and save_to_fs: |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
222 item_raw = json.dumps(item) |
|
61d606fbc313
bake: Change `show-timers` to `show-stats`, add stats.
Ludovic Chabant <ludovic@chabant.com>
parents:
424
diff
changeset
|
223 self.fs_cache.write(fs_key, item_raw) |
|
416
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
224 |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
225 return item |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
226 |
|
ff6cc43fb40c
internal: Move `MemCache` to the `cache` module, remove threading locks.
Ludovic Chabant <ludovic@chabant.com>
parents:
371
diff
changeset
|
227 |
