caches: introduce new conditional cache function.

This commit is contained in:
Marcin Kuzminski 2018-07-14 18:17:02 +02:00
parent 23c4d38e15
commit 6e45dc9605
3 changed files with 81 additions and 4 deletions

View file

@ -20,7 +20,6 @@
import logging
from dogpile.cache import register_backend
from dogpile.cache import make_region
register_backend(
"dogpile.cache.rc.memory_lru", "rhodecode.lib.rc_cache.backends",
@ -40,7 +39,7 @@ log = logging.getLogger(__name__)
from . import region_meta
from .utils import (
get_default_cache_settings, key_generator, get_or_create_region,
clear_cache_namespace)
clear_cache_namespace, make_region)
def configure_dogpile_cache(settings):

View file

@ -19,7 +19,10 @@
# and proprietary license terms, please see https://rhodecode.com/licenses/
import os
import logging
from dogpile.cache import make_region
import functools
from dogpile.cache import CacheRegion
from dogpile.cache.util import compat
from rhodecode.lib.utils import safe_str, sha1
from . import region_meta
@ -27,6 +30,82 @@ from . import region_meta
log = logging.getLogger(__name__)
class RhodeCodeCacheRegion(CacheRegion):
def conditional_cache_on_arguments(
self, namespace=None,
expiration_time=None,
should_cache_fn=None,
to_str=compat.string_type,
function_key_generator=None,
condition=True):
"""
Custom conditional decorator, that will not touch any dogpile internals if
condition isn't meet. This works a bit different than should_cache_fn
And it's faster in cases we don't ever want to compute cached values
"""
expiration_time_is_callable = compat.callable(expiration_time)
if function_key_generator is None:
function_key_generator = self.function_key_generator
def decorator(fn):
if to_str is compat.string_type:
# backwards compatible
key_generator = function_key_generator(namespace, fn)
else:
key_generator = function_key_generator(namespace, fn, to_str=to_str)
@functools.wraps(fn)
def decorate(*arg, **kw):
key = key_generator(*arg, **kw)
@functools.wraps(fn)
def creator():
return fn(*arg, **kw)
if not condition:
return creator()
timeout = expiration_time() if expiration_time_is_callable \
else expiration_time
return self.get_or_create(key, creator, timeout, should_cache_fn)
def invalidate(*arg, **kw):
key = key_generator(*arg, **kw)
self.delete(key)
def set_(value, *arg, **kw):
key = key_generator(*arg, **kw)
self.set(key, value)
def get(*arg, **kw):
key = key_generator(*arg, **kw)
return self.get(key)
def refresh(*arg, **kw):
key = key_generator(*arg, **kw)
value = fn(*arg, **kw)
self.set(key, value)
return value
decorate.set = set_
decorate.invalidate = invalidate
decorate.refresh = refresh
decorate.get = get
decorate.original = fn
decorate.key_generator = key_generator
return decorate
return decorator
def make_region(*arg, **kw):
return RhodeCodeCacheRegion(*arg, **kw)
def get_default_cache_settings(settings, prefixes=None):
prefixes = prefixes or []
cache_settings = {}

View file

@ -120,7 +120,6 @@ def get_repo_group_slug(request):
# pyramid
_group = request.matchdict.get('repo_group_name')
if _group:
_group = _group.rstrip('/')
return _group