initial commit
This commit is contained in:
105
cassandra_sessions/__init__.py
Normal file
105
cassandra_sessions/__init__.py
Normal file
@@ -0,0 +1,105 @@
|
||||
import lazyboy
|
||||
import time
|
||||
import logging
|
||||
from lazyboy.key import Key
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.utils.encoding import force_unicode
|
||||
from django.contrib.sessions.backends.base import SessionBase, CreateError
|
||||
|
||||
CASSANDRA_POOL = getattr(settings, 'CASSANDRA_POOL', None)
|
||||
CASSANDRA_SESSION_KEYSPACE = getattr(settings, 'CASSANDRA_SESSION_KEYSPACE', None)
|
||||
|
||||
if CASSANDRA_POOL is None or CASSANDRA_SESSION_KEYSPACE is None:
|
||||
raise ImproperlyConfigured(u'To use cassandra-sessions, you must first set the CASSANDRA_SESSION_KEYSPACE and CASSANDRA_POOL settings in your settings.py')
|
||||
else:
|
||||
try:
|
||||
lazyboy.connection.get_pool(CASSANDRA_SESSION_KEYSPACE)
|
||||
except lazyboy.exceptions.ErrorCassandraClientNotFound:
|
||||
lazyboy.connection.add_pool(CASSANDRA_SESSION_KEYSPACE, CASSANDRA_POOL)
|
||||
|
||||
class SessionStore(SessionBase):
|
||||
"""
|
||||
A Cassandra-based session store.
|
||||
"""
|
||||
|
||||
def get_session(self, session_key):
|
||||
logging.debug('Getting session: %s' % session_key)
|
||||
session = None
|
||||
if session_key:
|
||||
try:
|
||||
key = Key(
|
||||
keyspace=CASSANDRA_SESSION_KEYSPACE,
|
||||
column_family="Sessions",
|
||||
key=session_key
|
||||
)
|
||||
record = lazyboy.record.Record()
|
||||
session_record = record.load(key)
|
||||
session_values = session_record.values()
|
||||
if session_values:
|
||||
session = session_values[0]
|
||||
except lazyboy.exceptions.ErrorNoSuchRecord:
|
||||
pass
|
||||
return session
|
||||
|
||||
def load(self):
|
||||
session_data = self.get_session(self.session_key)
|
||||
if session_data is not None:
|
||||
expiry, data = int(session_data[:15]), session_data[15:]
|
||||
if expiry < time.time():
|
||||
return {}
|
||||
else:
|
||||
return self.decode(force_unicode(data))
|
||||
self.create()
|
||||
return {}
|
||||
|
||||
def create(self):
|
||||
while True:
|
||||
self.session_key = self._get_new_session_key()
|
||||
try:
|
||||
self.save()
|
||||
except CreateError:
|
||||
continue
|
||||
self.modified = True
|
||||
return
|
||||
|
||||
def save(self, must_create=True):
|
||||
data = self.encode(self._get_session(no_load=True))
|
||||
encoded = '%15d%s' % (int(time.time()) + self.get_expiry_age(), data)
|
||||
key = Key(
|
||||
keyspace=CASSANDRA_SESSION_KEYSPACE,
|
||||
column_family="Sessions",
|
||||
key=self.session_key
|
||||
)
|
||||
record = lazyboy.record.Record()
|
||||
record.key = key
|
||||
record[self.session_key] = encoded
|
||||
record.save()
|
||||
|
||||
def exists(self, session_key):
|
||||
session_data = self.get_session(session_key)
|
||||
if session_data is not None:
|
||||
expiry, data = int(session_data[:15]), session_data[15:]
|
||||
if expiry < time.time():
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
return False
|
||||
|
||||
def delete(self, session_key=None):
|
||||
if session_key is None:
|
||||
if self._session_key is None:
|
||||
return
|
||||
session_key = self._session_key
|
||||
key = Key(
|
||||
keyspace=CASSANDRA_SESSION_KEYSPACE,
|
||||
column_family="Sessions",
|
||||
key=session_key
|
||||
)
|
||||
# make this session expire right now
|
||||
data = self.encode({})
|
||||
encoded = '%15d%s' % (int(time.time()), data)
|
||||
record = lazyboy.record.Record()
|
||||
record.key = key
|
||||
record[self.session_key] = encoded
|
||||
record.save()
|
||||
13
cassandra_sessions/settings.py
Normal file
13
cassandra_sessions/settings.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import lazyboy
|
||||
import logging
|
||||
|
||||
logging.basicConfig(
|
||||
level = logging.DEBUG,
|
||||
format = '[%(asctime)s] %(levelname)s: "%(message)s"',
|
||||
datefmt = '%d/%b/%Y %I:%M:%S'
|
||||
)
|
||||
|
||||
CASSANDRA_POOL = ('127.0.0.1:9160',)
|
||||
CASSANDRA_SESSION_KEYSPACE = 'Testing'
|
||||
|
||||
lazyboy.connection.add_pool(CASSANDRA_SESSION_KEYSPACE, CASSANDRA_POOL)
|
||||
46
cassandra_sessions/test.py
Normal file
46
cassandra_sessions/test.py
Normal file
@@ -0,0 +1,46 @@
|
||||
"""
|
||||
>>> from django.conf import settings
|
||||
>>> from cassandra_sessions import SessionStore as CassandraSession
|
||||
>>> cassandra_session = CassandraSession()
|
||||
>>> cassandra_session.modified
|
||||
False
|
||||
>>> cassandra_session.get('cat')
|
||||
>>> cassandra_session['cat'] = "dog"
|
||||
>>> cassandra_session.modified
|
||||
True
|
||||
>>> cassandra_session.pop('cat')
|
||||
'dog'
|
||||
>>> cassandra_session.pop('some key', 'does not exist')
|
||||
'does not exist'
|
||||
>>> cassandra_session.save()
|
||||
>>> cassandra_session.exists(cassandra_session.session_key)
|
||||
True
|
||||
>>> cassandra_session.delete(cassandra_session.session_key)
|
||||
>>> cassandra_session['foo'] = 'bar'
|
||||
>>> cassandra_session.save()
|
||||
>>> cassandra_session.exists(cassandra_session.session_key)
|
||||
True
|
||||
>>> prev_key = cassandra_session.session_key
|
||||
>>> cassandra_session.flush()
|
||||
>>> cassandra_session.exists(prev_key)
|
||||
False
|
||||
>>> cassandra_session.session_key == prev_key
|
||||
False
|
||||
>>> cassandra_session.modified, cassandra_session.accessed
|
||||
(True, True)
|
||||
>>> cassandra_session['a'], cassandra_session['b'] = 'c', 'd'
|
||||
>>> cassandra_session.save()
|
||||
>>> prev_key = cassandra_session.session_key
|
||||
>>> prev_data = cassandra_session.items()
|
||||
>>> cassandra_session.cycle_key()
|
||||
>>> cassandra_session.session_key == prev_key
|
||||
False
|
||||
>>> cassandra_session.items() == prev_data
|
||||
True
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
Reference in New Issue
Block a user