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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
"""
Cached, database-backed sessions.
"""
import logging
from django.conf import settings
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.core.cache import caches
KEY_PREFIX = "django.contrib.sessions.cached_db"
logger = logging.getLogger("django.contrib.sessions")
class SessionStore(DBStore):
"""
Implement cached, database backed sessions.
"""
cache_key_prefix = KEY_PREFIX
def __init__(self, session_key=None):
self._cache = caches[settings.SESSION_CACHE_ALIAS]
super().__init__(session_key)
@property
def cache_key(self):
return self.cache_key_prefix + self._get_or_create_session_key()
async def acache_key(self):
return self.cache_key_prefix + await self._aget_or_create_session_key()
def load(self):
try:
data = self._cache.get(self.cache_key)
except Exception:
# Some backends (e.g. memcache) raise an exception on invalid
# cache keys. If this happens, reset the session. See #17810.
data = None
if data is None:
s = self._get_session_from_db()
if s:
data = self.decode(s.session_data)
self._cache.set(
self.cache_key, data, self.get_expiry_age(expiry=s.expire_date)
)
else:
data = {}
return data
async def aload(self):
try:
data = await self._cache.aget(await self.acache_key())
except Exception:
# Some backends (e.g. memcache) raise an exception on invalid
# cache keys. If this happens, reset the session. See #17810.
data = None
if data is None:
s = await self._aget_session_from_db()
if s:
data = self.decode(s.session_data)
await self._cache.aset(
await self.acache_key(),
data,
await self.aget_expiry_age(expiry=s.expire_date),
)
else:
data = {}
return data
def exists(self, session_key):
return (
session_key
and (self.cache_key_prefix + session_key) in self._cache
or super().exists(session_key)
)
async def aexists(self, session_key):
return (
session_key
and (self.cache_key_prefix + session_key) in self._cache
or await super().aexists(session_key)
)
def save(self, must_create=False):
super().save(must_create)
try:
self._cache.set(self.cache_key, self._session, self.get_expiry_age())
except Exception:
logger.exception("Error saving to cache (%s)", self._cache)
async def asave(self, must_create=False):
await super().asave(must_create)
try:
await self._cache.aset(
await self.acache_key(),
self._session,
await self.aget_expiry_age(),
)
except Exception:
logger.exception("Error saving to cache (%s)", self._cache)
def delete(self, session_key=None):
super().delete(session_key)
if session_key is None:
if self.session_key is None:
return
session_key = self.session_key
self._cache.delete(self.cache_key_prefix + session_key)
async def adelete(self, session_key=None):
await super().adelete(session_key)
if session_key is None:
if self.session_key is None:
return
session_key = self.session_key
await self._cache.adelete(self.cache_key_prefix + session_key)
def flush(self):
"""
Remove the current session data from the database and regenerate the
key.
"""
self.clear()
self.delete(self.session_key)
self._session_key = None
async def aflush(self):
"""See flush()."""
self.clear()
await self.adelete(self.session_key)
self._session_key = None
|