remove custom caches

My RamSession and PostgresSession were needed because the CherryPy version we were using was not compatible with Python 3. Current versions are compatible, so these are not needed.
onedrive
eric 2019-04-05 17:30:33 -04:00
parent 64717ce0c2
commit 22e0522a37
3 changed files with 0 additions and 298 deletions

View File

@ -51,12 +51,6 @@ import Formatters
import RateLimiter import RateLimiter
import Timer import Timer
import MyRamSession
import PostgresSession
cherrypy.lib.sessions.RamSession = MyRamSession.FixedRamSession
cherrypy.lib.sessions.MyramSession = MyRamSession.MyRamSession
cherrypy.lib.sessions.PostgresSession = PostgresSession.PostgresSession
plugins.Timer = Timer.TimerPlugin plugins.Timer = Timer.TimerPlugin

View File

@ -1,141 +0,0 @@
#!/usr/bin/env python
# -*- mode: python; indent-tabs-mode: nil; -*- coding: utf-8 -*-
"""
MyRamSession.py
Copyright 2014 by Marcello Perathoner
Distributable under the GNU General Public License Version 3 or newer.
A quick Python3 fix for the cherrypy RamSession. May be removed when
RamSession is fixed upstream.
Usage:
import MyRamSession
cherrypy.lib.sessions.RamSession = MyRamSession.FixedRamSession
cherrypy.lib.sessions.MyramSession = MyRamSession.MyRamSession
"""
import threading
import cherrypy
import cherrypy.lib.sessions
class Struct (object):
""" Data store. """
def __init__ (self):
self.expires = None
self.data = None
self.cache_lock = threading.Lock ()
class MyRamSession (cherrypy.lib.sessions.Session):
""" A cherrypy session kept in ram. """
cache = {}
# all inserts/deletes in cache must be guarded by this lock
# or we will get 'RuntimeError: dictionary changed size during iteration'
# because you cannot atomically iterate a dict in Python3
cache_lock = threading.Lock ()
def __init__ (self, id_ = None, **kwargs):
super (MyRamSession, self).__init__ (id_, **kwargs)
def clean_up (self):
"""Clean up expired sessions."""
now = self.now ()
def expired (x):
return x[1].expires <= now
with self.cache_lock:
for id_, s in list (filter (expired, self.cache.items ())):
self.cache.pop (id_, None)
def _exists (self):
return self.id in self.cache
def _load (self):
try:
s = self.cache[self.id]
return s.data, s.expires
except KeyError:
return None
def _save (self, expires):
s = self.cache.get (self.id, Struct ())
s.expires = expires
s.data = self._data
with self.cache_lock:
self.cache[self.id] = s
def _delete (self):
with self.cache_lock:
self.cache.pop (self.id, None)
def acquire_lock (self):
"""Acquire an exclusive lock on the currently-loaded session data."""
try:
self.cache[self.id].lock.acquire ()
self.locked = True
except KeyError:
pass
def release_lock (self):
"""Release the lock on the currently-loaded session data."""
try:
self.cache[self.id].lock.release ()
self.locked = False
except KeyError:
pass
def __len__ (self):
"""Return the number of active sessions."""
return len (self.cache)
from cherrypy._cpcompat import copyitems
class FixedRamSession (cherrypy.lib.sessions.RamSession):
def clean_up(self):
"""Clean up expired sessions."""
now = self.now()
try:
for id, (data, expiration_time) in copyitems(self.cache):
if expiration_time <= now:
try:
del self.cache[id]
except KeyError:
pass
try:
del self.locks[id]
except KeyError:
pass
# added to remove obsolete lock objects
for id in list(self.locks):
if id not in self.cache:
self.locks.pop(id, None)
except RuntimeError:
# RuntimeError: dictionary changed size during iteration
# Do nothig. Keep cleanup thread running and maybe next time lucky.
pass

View File

@ -1,151 +0,0 @@
#!/usr/bin/env python
# -*- mode: python; indent-tabs-mode: nil; -*- coding: utf-8 -*-
"""
PostgresSession.py
Copyright 2014 by Marcello Perathoner
Distributable under the GNU General Public License Version 3 or newer.
A rewrite of the cherrypy PostgresqlSession.
Usage:
import PostgresSession
cherrypy.lib.sessions.PostgresSession = PostgresSession.PostgresSession
"""
import datetime
import logging
import pickle
import cherrypy
import cherrypy.lib.sessions
class PostgresSession (cherrypy.lib.sessions.Session):
""" Implementation of the PostgreSQL backend for sessions. It assumes
a table like this::
create table <table_name> (
id varchar (40) primary key,
expires timestamp,
data bytea
)
You must provide your own `get_dbapi20_connection ()` function.
"""
pickle_protocol = pickle.HIGHEST_PROTOCOL
select = 'select expires, data from table_name where id=%(id)s for update'
def __init__ (self, id_ = None, **kwargs):
self.table_name = kwargs.get ('table', 'session')
# Session.__init__ () may need working connection
self.connection = self.get_dbapi20_connection ()
super (PostgresSession, self).__init__ (id_, **kwargs)
@staticmethod
def get_dbapi20_connection ():
""" Return a dbapi 2.0 compatible connection. """
return cherrypy.engine.pool.connect ()
@classmethod
def setup (cls, **kwargs):
"""Set up the storage system for Postgres-based sessions.
This should only be called once per process; this will be done
automatically when using sessions.init (as the built-in Tool does).
"""
cherrypy.log ("Using PostgresSession",
context = 'SESSION', severity = logging.INFO)
for k, v in kwargs.items ():
setattr (cls, k, v)
def now (self):
"""Generate the session specific concept of 'now'.
Other session providers can override this to use alternative,
possibly timezone aware, versions of 'now'.
"""
return datetime.datetime.utcnow ()
def _exec (self, sql, **kwargs):
""" Internal helper to execute sql statements. """
kwargs['id'] = self.id
cursor = self.connection.cursor ()
cursor.execute (sql.replace ('table_name', self.table_name), kwargs)
return cursor
def _exists (self):
""" Return true if session data exists. """
cursor = self._exec (self.select)
return bool (cursor.fetchall ())
def _load (self):
""" Load the session data. """
cursor = self._exec (self.select)
rows = cursor.fetchall ()
if not rows:
return None
expires, pickled_data = rows[0]
data = pickle.loads (pickled_data)
return data, expires
def _save (self, expires):
""" Save the session data. """
pickled_data = pickle.dumps (self._data, self.pickle_protocol)
self._delete ()
self._exec (
"""\
insert into table_name (id, expires, data)
values (%(id)s, %(expires)s, %(data)s)
""",
data = pickled_data,
expires = expires
)
def _delete (self):
""" Delete the session data. """
self._exec ('delete from table_name where id=%(id)s')
def acquire_lock (self):
"""Acquire an exclusive lock on the currently-loaded session data."""
self._exec (self.select)
self.locked = True
def release_lock (self):
"""Release the lock on the currently-loaded session data."""
self.connection.commit ()
self.locked = False
def clean_up (self):
"""Clean up expired sessions."""
self._exec (
'delete from table_name where expires < %(now)s',
now = self.now ()
)