-
Notifications
You must be signed in to change notification settings - Fork 896
Expand file tree
/
Copy pathrediscache.py
More file actions
57 lines (45 loc) · 1.85 KB
/
rediscache.py
File metadata and controls
57 lines (45 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""
This is an example of a library written to work with opentracing-python. It
provides a simple caching decorator backed by Redis, and uses the OpenTracing
Redis integration to automatically generate spans for each call to Redis.
"""
import pickle
from functools import wraps
import redis
import redis_opentracing
class RedisCache:
"""Redis-backed caching decorator, using OpenTracing!
Args:
tracer: an opentracing.tracer.Tracer
"""
def __init__(self, tracer):
redis_opentracing.init_tracing(tracer)
self.tracer = tracer
self.client = redis.StrictRedis()
def __call__(self, func):
@wraps(func)
def inner(*args, **kwargs):
with self.tracer.start_active_span("Caching decorator") as scope1:
# Pickle the call args to get a canonical key. Don't do this in
# prod!
key = pickle.dumps((func.__qualname__, args, kwargs))
pval = self.client.get(key)
if pval is not None:
val = pickle.loads(pval)
scope1.span.log_kv(
{"msg": "Found cached value", "val": val}
)
return val
scope1.span.log_kv({"msg": "Cache miss, calling function"})
with self.tracer.start_active_span(
f'Call "{func.__name__}"'
) as scope2:
scope2.span.set_tag("func", func.__name__)
scope2.span.set_tag("args", str(args))
scope2.span.set_tag("kwargs", str(kwargs))
val = func(*args, **kwargs)
scope2.span.set_tag("val", str(val))
# Let keys expire after 10 seconds
self.client.setex(key, 10, pickle.dumps(val))
return val
return inner