|
0
|
1 |
from django.contrib.sessions.backends.base import SessionBase, CreateError |
|
|
2 |
from django.core.cache import cache |
|
|
3 |
|
|
|
4 |
class SessionStore(SessionBase): |
|
|
5 |
""" |
|
|
6 |
A cache-based session store. |
|
|
7 |
""" |
|
|
8 |
def __init__(self, session_key=None): |
|
|
9 |
self._cache = cache |
|
|
10 |
super(SessionStore, self).__init__(session_key) |
|
|
11 |
|
|
|
12 |
def load(self): |
|
|
13 |
session_data = self._cache.get(self.session_key) |
|
|
14 |
if session_data is not None: |
|
|
15 |
return session_data |
|
|
16 |
self.create() |
|
|
17 |
return {} |
|
|
18 |
|
|
|
19 |
def create(self): |
|
|
20 |
# Because a cache can fail silently (e.g. memcache), we don't know if |
|
|
21 |
# we are failing to create a new session because of a key collision or |
|
|
22 |
# because the cache is missing. So we try for a (large) number of times |
|
|
23 |
# and then raise an exception. That's the risk you shoulder if using |
|
|
24 |
# cache backing. |
|
|
25 |
for i in xrange(10000): |
|
|
26 |
self.session_key = self._get_new_session_key() |
|
|
27 |
try: |
|
|
28 |
self.save(must_create=True) |
|
|
29 |
except CreateError: |
|
|
30 |
continue |
|
|
31 |
self.modified = True |
|
|
32 |
return |
|
|
33 |
raise RuntimeError("Unable to create a new session key.") |
|
|
34 |
|
|
|
35 |
def save(self, must_create=False): |
|
|
36 |
if must_create: |
|
|
37 |
func = self._cache.add |
|
|
38 |
else: |
|
|
39 |
func = self._cache.set |
|
|
40 |
result = func(self.session_key, self._get_session(no_load=must_create), |
|
|
41 |
self.get_expiry_age()) |
|
|
42 |
if must_create and not result: |
|
|
43 |
raise CreateError |
|
|
44 |
|
|
|
45 |
def exists(self, session_key): |
|
|
46 |
if self._cache.has_key(session_key): |
|
|
47 |
return True |
|
|
48 |
return False |
|
|
49 |
|
|
|
50 |
def delete(self, session_key=None): |
|
|
51 |
if session_key is None: |
|
|
52 |
if self._session_key is None: |
|
|
53 |
return |
|
|
54 |
session_key = self._session_key |
|
|
55 |
self._cache.delete(session_key) |
|
|
56 |
|