RedisCache   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 50
Duplicated Lines 0 %

Importance

Changes 6
Bugs 1 Features 0
Metric Value
c 6
b 1
f 0
dl 0
loc 50
rs 10
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __client() 0 8 2
A lock() 0 2 1
A reset_all() 0 5 1
B locked_get_or_set() 0 29 6
1
from django.core.cache.backends.base import DEFAULT_TIMEOUT
2
from django_redis.cache import RedisCache as PlainRedisCache
3
4
from redis_lock import Lock
5
from redis_lock import reset_all
6
7
8
class RedisCache(PlainRedisCache):
9
10
    @property
11
    def __client(self):
12
        try:
13
            return self.client.get_client()
14
        except Exception as exc:
15
            raise NotImplementedError(
16
                "RedisCache doesn't have a raw client: %r. "
17
                "Use 'redis_cache.client.DefaultClient' as the CLIENT_CLASS !" % exc
18
            )
19
20
    def lock(self, key, expire=None, id=None):
21
        return Lock(self.__client, key, expire=expire, id=id)
22
23
    def locked_get_or_set(self, key, value_creator, version=None,
24
                          expire=None, id=None, lock_key=None,
25
                          timeout=DEFAULT_TIMEOUT):
26
        """
27
        Fetch a given key from the cache. If the key does not exist, the key is added and
28
        set to the value returned when calling `value_creator`. The creator function
29
        is invoked inside of a lock.
30
        """
31
        if lock_key is None:
32
            lock_key = 'get_or_set:' + key
33
34
        val = self.get(key, version=version)
35
        if val is not None:
36
            return val
37
38
        with self.lock(lock_key, expire=expire, id=id):
39
            # Was the value set while we were trying to acquire the lock?
40
            val = self.get(key, version=version)
41
            if val is not None:
42
                return val
43
44
            # Nope, create value now.
45
            val = value_creator()
46
47
            if val is None:
48
                raise ValueError('`value_creator` must return a value')
49
50
            self.set(key, val, timeout=timeout, version=version)
51
            return val
52
53
    def reset_all(self):
54
        """
55
        Forcibly deletes all locks if its remains (like a crash reason). Use this with care.
56
        """
57
        reset_all(self.__client)
58