Add option to ignore some parameters when making key
PaulRudin opened this issue · 3 comments
There are some occasions when it's useful to ignore some parameters for the purpose of determining a key. For example if you're caching a method, it might be that self
is irrelevant to the desired caching behaviour.
from cache import AsyncLRU
import asyncio
import time
class ClassFn:
@AsyncLRU(maxsize=128)
async def obj_f(self, wait: int):
await asyncio.sleep(wait)
@classmethod
@AsyncLRU(maxsize=128)
async def class_f(cls, wait: int):
await asyncio.sleep(wait)
def test_obj_fn():
t1 = time.time()
obj = ClassFn()
asyncio.get_event_loop().run_until_complete(obj.obj_f(4))
t2 = time.time()
asyncio.get_event_loop().run_until_complete(obj.obj_f(4))
t3 = time.time()
t_first_exec = (t2 - t1) * 1000
t_second_exec = (t3 - t2) * 1000
print(t_first_exec)
print(t_second_exec)
assert t_first_exec > 4000
assert t_second_exec < 4000
def test_class_fn():
t1 = time.time()
asyncio.get_event_loop().run_until_complete(ClassFn.class_f(4))
t2 = time.time()
asyncio.get_event_loop().run_until_complete(ClassFn.class_f(4))
t3 = time.time()
t_first_exec = (t2 - t1) * 1000
t_second_exec = (t3 - t2) * 1000
print(t_first_exec)
print(t_second_exec)
assert t_first_exec > 4000
assert t_second_exec < 4000
if __name__ == "__main__":
test_obj_fn()
test_class_fn()
@PaulRudin Used this script to verify that caching works even with functions with self
and cls
arguments. Can you add any other case where ignoring a function argument is required. Thanks!
The issue isn't that the caching fails. Rather there are occasions on which it would be convenient for some arguments (let's say just the first for now) are ignored when making the key (the thing about self
is just an possible example). So we'd get a cache hit when a method was called from different instances (i.e. different objects bound to self
).
aiocache has this kind of thing specifically for self: https://aiocache.readthedocs.io/en/latest/decorators.html#cached (see noself
) but it doesn't really need to be limited to the special case of self
.
So we might have something along the lines of:
@AsyncLRU(skip_args=1)
def foo(*args, **kwarg):
...
And the effect of this would be that the key is computed using args[1:]
rather than args
@PaulRudin Thanks for suggestion. Added skip args option for AsyncTTL
.
@AsyncTTL(maxsize=128, time_to_live=None, skip_args=1)
async def skip_arg_func(arg: int, wait: int):
await asyncio.sleep(wait)
Available in async-cache 1.1.1