|
perry.tew at cibavision.novartis.com
perry.tew at cibavision.novartis.com
Fri Oct 3 15:18:08 EST 2003
Hello,
I had need for global persistence in my mod_python application under
Solaris. I read Grisha's article last night talking about the new Session
code. I thought is was really useful. So I looked it over and used it as
a template for creating application level data sharing similar to Visual
Basic's Application object or JSP's application object. I basically
stripped out the cookie code, time stamping, and used a constant hash id
for retrieving the data.
I'm still raw to python. I was wondering if such functionality is needed
by the mod_python community or if such a thing already exists. I was also
hoping that if somebody did have a use for it then they could code review
it for me and hopefully provide criticism or optimizations on the code. If
neither, then I'll just keep it for my own use.
The code is listed below. I'm not sure if this mailing list accepts
attachments, so I'm providing it both ways.
Thanks,
Perry Tew
#######################################################################
from mod_python import apache
import _apache
import os
import time
import anydbm, whichdb
import cPickle
import tempfile
APP_SID = 'app.sid'
tempdir = tempfile.gettempdir()
class BaseApplication(dict):
def __init__(self, req, lock=1):
self._req = req
self._lock = lock
self._new = 1
self._created = 0
self._locked = 0
dict.__init__(self)
self.init_lock()
# attempt to load ourselves
#self.lock()
if self.load():
self._new = 0
if self._new:
self._created = time.time()
def load(self):
dict = self.do_load()
if dict == None:
return 0
self._created = dict["_created"]
self.update(dict["_data"])
return 1
def save(self):
dict = {"_data" : self.copy(),
"_created" : self._created}
self.do_save(dict)
def delete(self):
self.do_delete()
self.clear()
def init_lock(self):
pass
def lock(self):
if self._lock:
_apache._global_lock(self._req.server, None, 0)
self._locked = 1
def unlock(self):
if self._lock and self._locked:
_apache._global_unlock(self._req.server, None, 0)
self._locked = 0
def is_new(self):
return not not self._new
def created(self):
return self._created
def __del__(self):
self.unlock()
class DbmApplication(BaseApplication):
def __init__(self, req, dbm=None, dbmtype=anydbm):
if not dbm:
opts = req.get_options()
if opts.has_key("ApplicationDbm"):
dbm = opts["ApplicationDbm"]
else:
dbm = os.path.join(tempdir, req.server.server_hostname +
str(req.server.port))
self._dbmfile = dbm
self._dbmtype = dbmtype
BaseApplication.__init__(self, req)
def _set_dbm_type(self):
module = whichdb.whichdb(self._dbmfile)
if module:
self._dbmtype = __import__(module)
def _get_dbm(self):
result = self._dbmtype.open(self._dbmfile, 'c')
if self._dbmtype is anydbm:
self._set_dbm_type()
return result
def do_load(self):
_apache._global_lock(self._req.server, None, 0)
dbm = self._get_dbm()
try:
if dbm.has_key(APP_SID):
return cPickle.loads(dbm[APP_SID])
else:
return None
finally:
dbm.close()
_apache._global_unlock(self._req.server, None, 0)
def do_save(self, dict):
_apache._global_lock(self._req.server, None, 0)
dbm = self._get_dbm()
try:
dbm[APP_SID] = cPickle.dumps(dict)
finally:
dbm.close()
_apache._global_unlock(self._req.server, None, 0)
def do_delete(self):
_apache._global_lock(self._req.server, None, 0)
dbm = self._get_dbm()
try:
try:
del dbm[APP_SID]
except KeyError: pass
finally:
dbm.close()
_apache._global_unlock(self._req.server, None, 0)
class MemoryApplication(BaseApplication):
sdict = {}
def __init__(self, req):
BaseApplication.__init__(self, req)
def do_load(self):
if MemoryApplication.sdict.has_key(APP_SID):
return MemoryApplication.sdict[APP_SID]
return None
def do_save(self, dict):
MemoryApplication.sdict[APP_SID] = dict
def do_delete(self):
try:
del MemoryApplication.sdict[APP_SID]
except KeyError: pass
def Application(req):
threaded = _apache.mpm_query(apache.AP_MPMQ_IS_THREADED)
forked = _apache.mpm_query(apache.AP_MPMQ_IS_FORKED)
daemons = _apache.mpm_query(apache.AP_MPMQ_MAX_DAEMONS)
if (threaded and ((not forked) or (daemons == 1))):
return MemoryApplication(req)
else:
return DbmApplication(req)
#######################################################################
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Application.py
Type: application/octet-stream
Size: 7023 bytes
Desc: not available
Url : http://mailman.modpython.org/pipermail/mod_python/attachments/20031003/199b5fec/Application-0003.obj
|