Martijn Moeling
martijn at xs4us.nu
Wed Nov 28 03:04:23 EST 2007
See below what I did to use MySQL as a session store. This is done since I use multiple mod_python frond ends to connect to one DB server. Martijn (these are changes made to the original Session.py from the mod_python package) ########################################################################### ## MySQLSession ## M. Moeling, martijn at xs4us.nu <mailto:martijn at xs4us.nu> ## ## In order to use MySQLSession: ## in your handler.py: ## import MySQLdb ## ## Use: ## req.db = MySQLdb.connect(host=Chost,user=Cuser,passwd=Cpasswd,db=Cdb) ## req.cursor = req.db.cursor() ## ## When req.cursor is existing, Session.py will default to MySQLSession ## Can be overruled with pythonoptions in apacheconfig ## ## To create table in MySQL use the following: ## CREATE TABLE `Session` ( ## `sid` varchar(50) NOT NULL, ## `store` text NOT NULL, ## PRIMARY KEY (`sid`) ## ) TYPE=MyISAM; def MySQL_cleanup(req): req.cursor.execute("Select * from Session") AllSessions = req.cursor.fetchall() stale=0 total=0 for record in AllSessions: total+=1 session = cPickle.loads(record[1]) if (time.time() - session["_accessed"]) > session["_timeout"]: stale+=1 req.cursor.execute("DELETE FROM Session where sid='"+record[0]+"'") req.log_error("MySQLSession: Removed: "+str(stale)+" stale records from "+str(total)+" in total",apache.APLOG_NOTICE) class MySQLSession(BaseSession): def __init__(self, req, sid=0, secret=None, timeout=0, lock=1): BaseSession.__init__(self, req, sid=sid, secret=secret, timeout=timeout, lock=lock) def do_cleanup(self): self._req.register_cleanup(MySQL_cleanup, self._req) self._req.log_error("MySQLSession: registered session cleanup.",apache.APLOG_NOTICE) def do_load(self): self._req.cursor.execute("Select store from Session where sid='"+self._sid+"'") store=self._req.cursor.fetchone() if self._req.cursor.rowcount==1: return cPickle.loads(store[0].encode('utf-8')) return None def do_save(self, dict): self._req.cursor.execute("Select store from Session where sid='"+self._sid+"'") store=self._req.cursor.fetchone() if self._req.cursor.rowcount==1: Query="Update Session set store=\""+cPickle.dumps(dict)+"\" where sid='"+self._sid+"'" else: Query="Insert into Session (sid,store) values (\""+self._sid+"\",\""+cPickle.dumps(dict)+"\")" self._req.cursor.execute(Query) def do_delete(self): try: self._req.cursor.execute("DELETE FROM Session where sid='"+self._sid+"'") except: pass ########################################################################### ## Session ## Changes made for MySQLSession ## the application should set req.cursor as an MySQLdb cursor object def Session(req, sid=0, secret=None, timeout=0, lock=1): opts = req.get_options() if opts.has_key('session'): # Check the apache config for the type of session sess_type = opts['session'] else: ## MySQLSession is default when req.cursor exists if req.cursor: sess_type = 'MySQLSession' else: ## END of MySQLSession modification # no session class in config so get the default for the platform 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))): sess_type = 'MemorySession' else: sess_type = 'DbmSession' if sess_type == 'FileSession': sess = FileSession elif sess_type == 'DbmSession': sess = DbmSession elif sess_type == 'MemorySession': sess = MemorySession ## Added for MySQLSession elif sess_type == 'MySQLSession': sess = MySQLSession else: # TODO Add capability to load a user defined class # For now, just raise an exception. raise Exception, 'Unknown session type %s' % sess_type return sess(req, sid=sid, secret=secret, timeout=timeout, lock=lock) ________________________________ Van: mod_python-bounces at modpython.org namens David Janes Verzonden: di 27.11.2007 20:06 Aan: Harish Agarwal CC: mod_python at modpython.org; Graham Dumpleton Onderwerp: Re: [mod_python] Session Hanging Problems Here's what I'm experimenting with right now -- I'm subclassing FileSession and overriding all the lock methods. Obviously this will have to be adapted for people not working in the FileSession world. Regards, etc... class BMFileSession(Session.FileSession): def __init__(self, req, sid = None): self.bm_lockf = None ... more init stuff ... def lock(self): if self._lock: self.bm_lock(self._req.server, self._sid) self._locked = 1 self._req.register_cleanup(Session.unlock_session_cleanup, self) def unlock(self): if self._lock and self._locked: self.bm_unlock(self._req.server, self._sid) self._locked = 0 def lock_file(self): if not self._locked: self.bm_lock(self._req.server, self._sid) self._locked = 1 def unlock_file(self): if self._locked and not self._lock: self.bm_unlock(self._req.server, self._sid) self._locked = 0 def bm_lockfile(self, sid): lockdir = os.path.join(self._sessdir, sid[:2]) if not os.path.exists(lockdir): os.makedirs(lockdir) return os.path.join(lockdir, sid) def bm_lock(self, server, sid): if self.bm_lockf: try: self.bm_lockf.close() except: pass self.bm_lockf = open(self.bm_lockfile(sid), 'a+') fcntl.lockf(self.bm_lockf, fcntl.LOCK_EX) def bm_unlock(self, server, sid): if self.bm_lockf: fcntl.lockf(self.bm_lockf, fcntl.LOCK_UN) try: self.bm_lockf.close() except: pass self.bm_lockf = None _______________________________________________ Mod_python mailing list Mod_python at modpython.org http://mailman.modpython.org/mailman/listinfo/mod_python -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mm_cfg_has_not_been_edited_to_set_host_domains/pipermail/mod_python/attachments/20071128/0aaa4735/attachment.html
|