def test_invalidate(self): cache = DeferredCache("test") cache.prefill(("foo",), 123) cache.invalidate(("foo",)) with self.assertRaises(KeyError): cache.get(("foo",))
def test_invalidate(self): cache = DeferredCache("test") cache.prefill(("foo", ), 123) cache.invalidate(("foo", )) failed = False try: cache.get(("foo", )) except KeyError: failed = True self.assertTrue(failed)
def __get__(self, obj, owner): cache = DeferredCache( name=self.orig.__name__, max_entries=self.max_entries, keylen=self.num_args, tree=self.tree, iterable=self.iterable, ) # type: DeferredCache[CacheKey, Any] get_cache_key = self.cache_key_builder @functools.wraps(self.orig) def _wrapped(*args, **kwargs): # If we're passed a cache_context then we'll want to call its invalidate() # whenever we are invalidated invalidate_callback = kwargs.pop("on_invalidate", None) cache_key = get_cache_key(args, kwargs) try: ret = cache.get(cache_key, callback=invalidate_callback) except KeyError: # Add our own `cache_context` to argument list if the wrapped function # has asked for one if self.add_cache_context: kwargs["cache_context"] = _CacheContext.get_instance( cache, cache_key ) ret = defer.maybeDeferred(preserve_fn(self.orig), obj, *args, **kwargs) ret = cache.set(cache_key, ret, callback=invalidate_callback) return make_deferred_yieldable(ret) wrapped = cast(_CachedFunction, _wrapped) if self.num_args == 1: wrapped.invalidate = lambda key: cache.invalidate(key[0]) wrapped.prefill = lambda key, val: cache.prefill(key[0], val) else: wrapped.invalidate = cache.invalidate wrapped.invalidate_many = cache.invalidate_many wrapped.prefill = cache.prefill wrapped.invalidate_all = cache.invalidate_all wrapped.cache = cache wrapped.num_args = self.num_args obj.__dict__[self.orig.__name__] = wrapped return wrapped
def __get__(self, obj, owner): cache = DeferredCache( name=self.orig.__name__, max_entries=self.max_entries, keylen=self.num_args, tree=self.tree, iterable=self.iterable, ) # type: DeferredCache[CacheKey, Any] def get_cache_key_gen(args, kwargs): """Given some args/kwargs return a generator that resolves into the cache_key. We loop through each arg name, looking up if its in the `kwargs`, otherwise using the next argument in `args`. If there are no more args then we try looking the arg name up in the defaults """ pos = 0 for nm in self.arg_names: if nm in kwargs: yield kwargs[nm] elif pos < len(args): yield args[pos] pos += 1 else: yield self.arg_defaults[nm] # By default our cache key is a tuple, but if there is only one item # then don't bother wrapping in a tuple. This is to save memory. if self.num_args == 1: nm = self.arg_names[0] def get_cache_key(args, kwargs): if nm in kwargs: return kwargs[nm] elif len(args): return args[0] else: return self.arg_defaults[nm] else: def get_cache_key(args, kwargs): return tuple(get_cache_key_gen(args, kwargs)) @functools.wraps(self.orig) def _wrapped(*args, **kwargs): # If we're passed a cache_context then we'll want to call its invalidate() # whenever we are invalidated invalidate_callback = kwargs.pop("on_invalidate", None) cache_key = get_cache_key(args, kwargs) try: ret = cache.get(cache_key, callback=invalidate_callback) except KeyError: # Add our own `cache_context` to argument list if the wrapped function # has asked for one if self.add_cache_context: kwargs["cache_context"] = _CacheContext.get_instance( cache, cache_key) ret = defer.maybeDeferred(preserve_fn(self.orig), obj, *args, **kwargs) ret = cache.set(cache_key, ret, callback=invalidate_callback) return make_deferred_yieldable(ret) wrapped = cast(_CachedFunction, _wrapped) if self.num_args == 1: wrapped.invalidate = lambda key: cache.invalidate(key[0]) wrapped.prefill = lambda key, val: cache.prefill(key[0], val) else: wrapped.invalidate = cache.invalidate wrapped.invalidate_all = cache.invalidate_all wrapped.invalidate_many = cache.invalidate_many wrapped.prefill = cache.prefill wrapped.invalidate_all = cache.invalidate_all wrapped.cache = cache wrapped.num_args = self.num_args obj.__dict__[self.orig.__name__] = wrapped return wrapped