CacheHandler.get_cache()   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
dl 0
loc 10
rs 9.2
c 0
b 0
f 0
1
# coding: utf-8
2
3
from __future__ import unicode_literals
4
from collections import defaultdict
5
from threading import local
6
7
from django.core.cache import caches
8
from django.db import DEFAULT_DB_ALIAS
9
10
from .settings import cachalot_settings
11
from .signals import post_invalidation
12
from .transaction import AtomicCache
13
14
15
class CacheHandler(local):
16
    @property
17
    def atomic_caches(self):
18
        if not hasattr(self, '_atomic_caches'):
19
            self._atomic_caches = defaultdict(list)
20
        return self._atomic_caches
21
22
    def get_atomic_cache(self, cache_alias, db_alias, level):
23
        if cache_alias not in self.atomic_caches[db_alias][level]:
24
            self.atomic_caches[db_alias][level][cache_alias] = AtomicCache(
25
                self.get_cache(cache_alias, db_alias, level-1), db_alias)
26
        return self.atomic_caches[db_alias][level][cache_alias]
27
28
    def get_cache(self, cache_alias=None, db_alias=None, atomic_level=-1):
29
        if db_alias is None:
30
            db_alias = DEFAULT_DB_ALIAS
31
        if cache_alias is None:
32
            cache_alias = cachalot_settings.CACHALOT_CACHE
33
34
        min_level = -len(self.atomic_caches[db_alias])
35
        if atomic_level < min_level:
36
            return caches[cache_alias]
37
        return self.get_atomic_cache(cache_alias, db_alias, atomic_level)
38
39
    def enter_atomic(self, db_alias):
40
        if db_alias is None:
41
            db_alias = DEFAULT_DB_ALIAS
42
        self.atomic_caches[db_alias].append({})
43
44
    def exit_atomic(self, db_alias, commit):
45
        if db_alias is None:
46
            db_alias = DEFAULT_DB_ALIAS
47
        atomic_caches = self.atomic_caches[db_alias].pop().values()
48
        if commit:
49
            to_be_invalidated = set()
50
            for atomic_cache in atomic_caches:
51
                atomic_cache.commit()
52
                to_be_invalidated.update(atomic_cache.to_be_invalidated)
53
            # This happens when committing the outermost atomic block.
54
            if not self.atomic_caches[db_alias]:
55
                for table in to_be_invalidated:
56
                    post_invalidation.send(table, db_alias=db_alias)
57
58
59
cachalot_caches = CacheHandler()
60