Make cache_context an explicit option

This commit is contained in:
Erik Johnston 2016-08-19 15:02:38 +01:00
parent f164fd9220
commit dc76a3e909
3 changed files with 30 additions and 11 deletions

View File

@ -134,7 +134,7 @@ class PushRuleStore(SQLBaseStore):
return self._bulk_get_push_rules_for_room(room_id, state_group, current_state) return self._bulk_get_push_rules_for_room(room_id, state_group, current_state)
@cachedInlineCallbacks(num_args=2) @cachedInlineCallbacks(num_args=2, cache_context=True)
def _bulk_get_push_rules_for_room(self, room_id, state_group, current_state, def _bulk_get_push_rules_for_room(self, room_id, state_group, current_state,
cache_context): cache_context):
# We don't use `state_group`, its there so that we can cache based # We don't use `state_group`, its there so that we can cache based

View File

@ -146,7 +146,7 @@ class CacheDescriptor(object):
invalidated) by adding a special "cache_context" argument to the function invalidated) by adding a special "cache_context" argument to the function
and passing that as a kwarg to all caches called. For example:: and passing that as a kwarg to all caches called. For example::
@cachedInlineCallbacks() @cachedInlineCallbacks(cache_context=True)
def foo(self, key, cache_context): def foo(self, key, cache_context):
r1 = yield self.bar1(key, cache_context=cache_context) r1 = yield self.bar1(key, cache_context=cache_context)
r2 = yield self.bar2(key, cache_context=cache_context) r2 = yield self.bar2(key, cache_context=cache_context)
@ -154,7 +154,7 @@ class CacheDescriptor(object):
""" """
def __init__(self, orig, max_entries=1000, num_args=1, tree=False, def __init__(self, orig, max_entries=1000, num_args=1, tree=False,
inlineCallbacks=False): inlineCallbacks=False, cache_context=False):
max_entries = int(max_entries * CACHE_SIZE_FACTOR) max_entries = int(max_entries * CACHE_SIZE_FACTOR)
self.orig = orig self.orig = orig
@ -171,15 +171,28 @@ class CacheDescriptor(object):
all_args = inspect.getargspec(orig) all_args = inspect.getargspec(orig)
self.arg_names = all_args.args[1:num_args + 1] self.arg_names = all_args.args[1:num_args + 1]
if "cache_context" in self.arg_names: if "cache_context" in all_args.args:
self.arg_names.remove("cache_context") if not cache_context:
raise ValueError(
"Cannot have a 'cache_context' arg without setting"
" cache_context=True"
)
try:
self.arg_names.remove("cache_context")
except ValueError:
pass
elif cache_context:
raise ValueError(
"Cannot have cache_context=True without having an arg"
" named `cache_context`"
)
self.add_cache_context = "cache_context" in all_args.args self.add_cache_context = cache_context
if len(self.arg_names) < self.num_args: if len(self.arg_names) < self.num_args:
raise Exception( raise Exception(
"Not enough explicit positional arguments to key off of for %r." "Not enough explicit positional arguments to key off of for %r."
" (@cached cannot key off of *args or **kwars)" " (@cached cannot key off of *args or **kwargs)"
% (orig.__name__,) % (orig.__name__,)
) )
@ -193,12 +206,16 @@ class CacheDescriptor(object):
@functools.wraps(self.orig) @functools.wraps(self.orig)
def wrapped(*args, **kwargs): def wrapped(*args, **kwargs):
# If we're passed a cache_context then we'll want to call its invalidate()
# whenever we are invalidated
cache_context = kwargs.pop("cache_context", None) cache_context = kwargs.pop("cache_context", None)
if cache_context: if cache_context:
context_callback = cache_context.invalidate context_callback = cache_context.invalidate
else: else:
context_callback = None context_callback = None
# Add our own `cache_context` to argument list if the wrapped function
# has asked for one
self_context = _CacheContext(cache, None) self_context = _CacheContext(cache, None)
if self.add_cache_context: if self.add_cache_context:
kwargs["cache_context"] = self_context kwargs["cache_context"] = self_context
@ -414,22 +431,24 @@ class _CacheContext(object):
self.cache.invalidate(self.key) self.cache.invalidate(self.key)
def cached(max_entries=1000, num_args=1, tree=False): def cached(max_entries=1000, num_args=1, tree=False, cache_context=False):
return lambda orig: CacheDescriptor( return lambda orig: CacheDescriptor(
orig, orig,
max_entries=max_entries, max_entries=max_entries,
num_args=num_args, num_args=num_args,
tree=tree, tree=tree,
cache_context=cache_context,
) )
def cachedInlineCallbacks(max_entries=1000, num_args=1, tree=False): def cachedInlineCallbacks(max_entries=1000, num_args=1, tree=False, cache_context=False):
return lambda orig: CacheDescriptor( return lambda orig: CacheDescriptor(
orig, orig,
max_entries=max_entries, max_entries=max_entries,
num_args=num_args, num_args=num_args,
tree=tree, tree=tree,
inlineCallbacks=True, inlineCallbacks=True,
cache_context=cache_context,
) )

View File

@ -211,7 +211,7 @@ class CacheDecoratorTestCase(unittest.TestCase):
callcount[0] += 1 callcount[0] += 1
return key return key
@cached() @cached(cache_context=True)
def func2(self, key, cache_context): def func2(self, key, cache_context):
callcount2[0] += 1 callcount2[0] += 1
return self.func(key, cache_context=cache_context) return self.func(key, cache_context=cache_context)
@ -244,7 +244,7 @@ class CacheDecoratorTestCase(unittest.TestCase):
callcount[0] += 1 callcount[0] += 1
return key return key
@cached() @cached(cache_context=True)
def func2(self, key, cache_context): def func2(self, key, cache_context):
callcount2[0] += 1 callcount2[0] += 1
return self.func(key, cache_context=cache_context) return self.func(key, cache_context=cache_context)