]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/plugins/ttl_cache.py
import 15.2.0 Octopus source
[ceph.git] / ceph / src / pybind / mgr / dashboard / plugins / ttl_cache.py
CommitLineData
11fdf7f2
TL
1"""
2This is a minimal implementation of TTL-ed lru_cache function.
3
4Based on Python 3 functools and backports.functools_lru_cache.
5"""
6from __future__ import absolute_import
7
8from functools import wraps
9from collections import OrderedDict
10from threading import RLock
11from time import time
12
9f95a23c
TL
13try:
14 from typing import Tuple
15except ImportError:
16 pass # For typing only
17
11fdf7f2
TL
18
19def ttl_cache(ttl, maxsize=128, typed=False):
20 if typed is not False:
21 raise NotImplementedError("typed caching not supported")
22
23 def decorating_function(function):
9f95a23c 24 cache = OrderedDict() # type: OrderedDict[object, Tuple[bool, float]]
11fdf7f2
TL
25 stats = [0, 0, 0]
26 rlock = RLock()
9f95a23c
TL
27 setattr(function, 'cache_info', lambda:
28 "hits={}, misses={}, expired={}, maxsize={}, currsize={}".format(
29 stats[0], stats[1], stats[2], maxsize, len(cache)))
11fdf7f2
TL
30
31 @wraps(function)
32 def wrapper(*args, **kwargs):
33 key = args + tuple(kwargs.items())
34 with rlock:
35 refresh = True
36 if key in cache:
37 (ret, ts) = cache[key]
38 del cache[key]
39 if time() - ts < ttl:
40 refresh = False
41 stats[0] += 1
42 else:
43 stats[2] += 1
44
45 if refresh:
46 ret = function(*args, **kwargs)
47 ts = time()
48 if len(cache) == maxsize:
49 cache.popitem(last=False)
50 stats[1] += 1
51
52 cache[key] = (ret, ts)
53
54 return ret
55
56 return wrapper
57 return decorating_function