0482dcc3ac
we don't use sessions for anything critial. the custom database session library locks the session for commit, and this happens every request, which is not optimal. for now, disable session locking.
74 lines
2.0 KiB
Python
74 lines
2.0 KiB
Python
import cherrypy
|
|
from photoapp.types import Base
|
|
from sqlalchemy import Column, String, DateTime, Boolean, BLOB
|
|
|
|
try:
|
|
import cPickle as pickle
|
|
except ImportError:
|
|
import pickle
|
|
|
|
|
|
class Session(Base):
|
|
__tablename__ = 'sessions'
|
|
session_id = Column(String(128), nullable=False, primary_key=True)
|
|
# user_id = Column(Integer, ForeignKey('users.user_id'))
|
|
expiration = Column(DateTime, nullable=False)
|
|
data = Column(BLOB)
|
|
is_valid = Column(Boolean, default=True, nullable=False)
|
|
|
|
|
|
class DatabaseSession(cherrypy.lib.sessions.Session):
|
|
"""
|
|
Sqlalchemy-backed backed for session storage. Note that we don't implement any of the locking methods because the
|
|
underlying database connection is being uses transaction anyway, which would prevent concurrent updates.
|
|
"""
|
|
@classmethod
|
|
def setup(cls, **kwargs):
|
|
for k, v in kwargs.items():
|
|
setattr(cls, k, v)
|
|
|
|
cls.cached = None
|
|
|
|
def _exists(self):
|
|
if not self.cached:
|
|
self._load()
|
|
return bool(self.cached)
|
|
|
|
def _load(self):
|
|
if not self.cached:
|
|
self.cached = cherrypy.request.db.query(Session).filter(Session.session_id == self.id).first()
|
|
# with_for_update()
|
|
|
|
if self.cached:
|
|
return pickle.loads(self.cached.data)
|
|
|
|
return None
|
|
|
|
def _save(self, expiration_time):
|
|
data = pickle.dumps(
|
|
(self._data, expiration_time),
|
|
pickle.HIGHEST_PROTOCOL)
|
|
|
|
if not self.cached:
|
|
self.cached = Session(session_id=self.id,
|
|
expiration=expiration_time)
|
|
cherrypy.request.db.add(self.cached)
|
|
|
|
self.cached.data = data
|
|
|
|
def _delete(self):
|
|
if not self.cached:
|
|
self._load()
|
|
|
|
if self.cached:
|
|
cherrypy.request.db.delete(self.cached)
|
|
|
|
def acquire_lock(self):
|
|
pass
|
|
|
|
def release_lock(self):
|
|
pass
|
|
|
|
def clean_up(self):
|
|
pass #TODO
|