# Copyright (C) 2004 Scott W. Dunlop <sdunlop at users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from exceptions import Exception
from threading import Lock,RLock,Thread
from time import time,sleep,gmtime
from weakref import ref
from random import Random
SESSION_TIMEOUT = 60 * 60
class SessionException(Exception):
pass
class SessionLogicError(SessionException):
pass
class SessionNotFound(SessionException):
def __init__(self, name=None, key=None):
if key is not None:
SessionException.__init__("Session '%s' was not found." % (key))
elif name is not None:
SessionException.__init__("Session for '%s' was not found." % (name))
else:
SessionException.__init__("A session was not found.")
class Session:
def __init__(self, name, key):
self.name = name
self.key = key
self.props = {}
self.lock = RLock()
self._mark()
def _mark(self):
self.lastTime = int(time())
def _get(self, key, default=None):
self._mark()
val = self.props.get(key)
if val is None:
self.props[key] = default
return default
else:
return val
def _set(self, key, value):
self._mark()
self.props[key] = value
def _del(self, key):
self._mark()
try:
del self.props[key]
except:
return
def getKey(self):
self.lock.acquire()
try:
ret = self.key
finally:
self.lock.release()
return ret
def getName(self):
self.lock.acquire()
try:
ret = self.name
finally:
self.lock.release()
return ret
def get(self, key, default=None):
self.lock.acquire()
try:
ret = self._get(key, default)
finally:
self.lock.release()
return ret
def set(self, key, value):
self.lock.acquire()
try:
ret = self._set(key,value)
finally:
self.lock.release()
return ret
def clear(self, key):
self.lock.acquire()
try:
ret = self._del(key)
finally:
self.lock.release()
return ret
def acquire(self):
self.lock.acquire()
def release(self):
self.lock.release()
class Server:
def __init__(self):
self.sessionsByName = {}
self.sessionsByKey = {}
self.sessions = []
self.lock = Lock()
self.random = Random()
self.sweeper = Sweeper(self)
def _sweepSessions(self):
now = int(time())
for session in self.sessions:
session.acquire()
try:
if (now - session.lastTime) > SESSION_TIMEOUT:
self._destroySession(session=session)
finally:
session.release()
def _getSession(self, name=None, key=None):
if name is not None:
session = self.sessionsByName.get(name)
elif key is not None:
session = self.sessionsByKey.get(key)
else:
raise SessionLogicError("Acquire Session was invoked without supplying a name or key.")
return session
def _createSession(self, name=None):
if name is None:
name = self._generateName()
else:
session = self._getSession(name=name)
if session is not None:
return session
key = self._generateKey()
session = Session(name, key)
self.sessionsByName[name] = session
self.sessionsByKey[key] = session
self.sessions.append(session)
return session
def _destroySession(self, name=None, key=None, session=None):
if session is None:
session = self._getSession(name=name, key=key)
if session is not None:
self.sessions.remove(session)
if key is not None:
del self.sessionsByKey[key]
if name is not None:
del self.sessionsByName[name]
def createSession(self, name=None):
self.lock.acquire()
try:
ret = self._createSession(name)
finally:
self.lock.release()
return ret
def getSession(self, name=None, key=None):
self.lock.acquire()
try:
ret = self._getSession(name=name, key=key)
finally:
self.lock.release()
return ret
def destroySession(self, name=None, key=None, session=None):
self.lock.acquire()
try:
ret = self._destroySession(name=name, key=key, session=session)
finally:
self.lock.release()
return ret
def sweepSessions(self):
self.lock.acquire()
try:
ret = self._sweepSessions()
finally:
self.lock.release()
return ret
def _generateRandomString(self):
return generate_random_string( )
def _generateKey(self):
while 1:
key = self._generateRandomString()
if self.sessionsByKey.get(key) is None:
return key
def _generateName(self):
while 1:
name = self._generateRandomString()
if self.sessionsByName.get(name) is None:
return name
class Sweeper(Thread):
def __init__(self, server):
self.server = weakref(server)
Thread.__init__(self)
self.setDaemon(1)
def run(self):
while 1:
sleep(SESSION_TIMEOUT)
server = self.server()
if server is not None:
server.sweepSessions()
else:
break
def generate_random_string( ):
st = ""
for i in range(0,32):
st += Codex.random.choice(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
)
return st
Codex = Server()
Codex.sweeper.start()
|