Merge branch 'maintenance' into devel
Conflicts: src/octoprint/server/util/flask.py
This commit is contained in:
commit
73e8d5e0a9
2 changed files with 41 additions and 10 deletions
|
|
@ -473,7 +473,9 @@ class LessSimpleCache(BaseCache):
|
|||
|
||||
def __init__(self, threshold=500, default_timeout=300):
|
||||
BaseCache.__init__(self, default_timeout=default_timeout)
|
||||
self._mutex = threading.RLock()
|
||||
self._cache = {}
|
||||
self._bypassed = set()
|
||||
self.clear = self._cache.clear
|
||||
self._threshold = threshold
|
||||
|
||||
|
|
@ -482,27 +484,35 @@ class LessSimpleCache(BaseCache):
|
|||
now = time.time()
|
||||
for idx, (key, (expires, _)) in enumerate(self._cache.items()):
|
||||
if expires is not None and expires <= now or idx % 3 == 0:
|
||||
self._cache.pop(key, None)
|
||||
with self._mutex:
|
||||
self._cache.pop(key, None)
|
||||
|
||||
def get(self, key):
|
||||
import pickle
|
||||
now = time.time()
|
||||
expires, value = self._cache.get(key, (0, None))
|
||||
with self._mutex:
|
||||
expires, value = self._cache.get(key, (0, None))
|
||||
if expires is None or expires > now:
|
||||
return pickle.loads(value)
|
||||
|
||||
def set(self, key, value, timeout=None):
|
||||
import pickle
|
||||
self._prune()
|
||||
self._cache[key] = (self.calculate_timeout(timeout=timeout),
|
||||
pickle.dumps(value, pickle.HIGHEST_PROTOCOL))
|
||||
|
||||
with self._mutex:
|
||||
self._prune()
|
||||
self._cache[key] = (self.calculate_timeout(timeout=timeout),
|
||||
pickle.dumps(value, pickle.HIGHEST_PROTOCOL))
|
||||
if key in self._bypassed:
|
||||
self._bypassed.remove(key)
|
||||
|
||||
def add(self, key, value, timeout=None):
|
||||
self.set(key, value, timeout=None)
|
||||
self._cache.setdefault(key, self._cache[key])
|
||||
with self._mutex:
|
||||
self.set(key, value, timeout=None)
|
||||
self._cache.setdefault(key, self._cache[key])
|
||||
|
||||
def delete(self, key):
|
||||
self._cache.pop(key, None)
|
||||
with self._mutex:
|
||||
self._cache.pop(key, None)
|
||||
|
||||
def calculate_timeout(self, timeout=None):
|
||||
if timeout is None:
|
||||
|
|
@ -514,7 +524,8 @@ class LessSimpleCache(BaseCache):
|
|||
def over_threshold(self):
|
||||
if self._threshold is None:
|
||||
return False
|
||||
return len(self._cache) > self._threshold
|
||||
with self._mutex:
|
||||
return len(self._cache) > self._threshold
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.get(key)
|
||||
|
|
@ -526,7 +537,16 @@ class LessSimpleCache(BaseCache):
|
|||
return self.delete(key)
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self._cache
|
||||
with self._mutex:
|
||||
return key in self._cache
|
||||
|
||||
def set_bypassed(self, key):
|
||||
with self._mutex:
|
||||
self._bypassed.add(key)
|
||||
|
||||
def is_bypassed(self, key):
|
||||
with self._mutex:
|
||||
return key in self._bypassed
|
||||
|
||||
_cache = LessSimpleCache()
|
||||
|
||||
|
|
@ -552,11 +572,13 @@ def cached(timeout=5 * 60, key=lambda: "view:%s" % flask.request.path, unless=No
|
|||
# bypass the cache if "unless" condition is true
|
||||
if callable(unless) and unless():
|
||||
logger.debug("Cache for {path} bypassed, calling wrapped function".format(path=flask.request.path))
|
||||
_cache.set_bypassed(cache_key)
|
||||
return f_with_duration(*args, **kwargs)
|
||||
|
||||
# also bypass the cache if it's disabled completely
|
||||
if not settings().getBoolean(["devel", "cache", "enabled"]):
|
||||
logger.debug("Cache for {path} disabled, calling wrapped function".format(path=flask.request.path))
|
||||
_cache.set_bypassed(cache_key)
|
||||
return f_with_duration(*args, **kwargs)
|
||||
|
||||
rv = _cache.get(cache_key)
|
||||
|
|
@ -575,6 +597,7 @@ def cached(timeout=5 * 60, key=lambda: "view:%s" % flask.request.path, unless=No
|
|||
# do not store if the "unless_response" condition is true
|
||||
if callable(unless_response) and unless_response(rv):
|
||||
logger.debug("Not caching result for {path} (key: {key}), bypassed".format(path=flask.request.path, key=cache_key))
|
||||
_cache.set_bypassed(cache_key)
|
||||
return rv
|
||||
|
||||
# store it in the cache
|
||||
|
|
@ -591,6 +614,11 @@ def is_in_cache(key=lambda: "view:%s" % flask.request.path):
|
|||
key = key()
|
||||
return key in _cache
|
||||
|
||||
def is_cache_bypassed(key=lambda: "view:%s" % flask.request.path):
|
||||
if callable(key):
|
||||
key = key()
|
||||
return _cache.is_bypassed(key)
|
||||
|
||||
def cache_check_headers():
|
||||
return "no-cache" in flask.request.cache_control or "no-cache" in flask.request.pragma
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,9 @@ def in_cache():
|
|||
elif util.flask.is_in_cache(key):
|
||||
_logger.info("Found path {} in cache (key: {}), signaling as cached".format(path, key))
|
||||
return response
|
||||
elif util.flask.is_cache_bypassed(key):
|
||||
_logger.info("Path {} was bypassed from cache (key: {}), signaling as cached".format(path, key))
|
||||
return response
|
||||
else:
|
||||
_logger.debug("Path {} not yet cached (key: {}), signaling as missing".format(path, key))
|
||||
return abort(404)
|
||||
|
|
|
|||
Loading…
Reference in a new issue