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
|