[mod_python] MySQLSession available!!

Graham Dumpleton grahamd at dscpl.com.au
Mon Nov 27 16:03:55 EST 2006


Database backed session classes have been discussed before on the mailing
list with examples posted. Use the search box on the mod_python web site to
search for the past posts. For example:

  http://www.modpython.org/pipermail/mod_python/2006-June/021433.html

There is no need for you to embed your session class within the mod_python
Session.py code file. Keep it separate. Database backed session classes are
unlikely to be included in mod_python as that then imposes a dependency on
a third party package which isn't something we really want to have to have
because of maintenance/support issues.

Graham

Martijn Moeling wrote ..
> Well after investigating "sessions.py" a bit more I have come up with a
> working MySQLSession object added to "sessions.py"
> 
> See code (only the changed parts) below....
> 
> The nasty thing is that it will be overwritten by any mod_python
> updates, or if it is interesting enough (hopefully) it gets into the
> next major mod_python release.
> 
> By checking for the req.cursor, there is no need for importing MySQLdb
> into session.py
> 
> See code (only the changed parts) below....
> 
> 8<---------------------------------------------------------------------
> ########################################################################
> ###
> ## MySQLSession
> ## M. Moeling, martijn at xs4us.nu
> ##
> ## In order to use MySQLSession:
> ## in your handler.py:        
> ## import MySQLdb
> ##
> ##  Somewhere before the session stuff 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 apache config
> ##
> ## 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()
>     for records in AllSessions:
>         session = cPicle.loads(record[1])
>         if (time.time() - session["_accessed"]) > session["_timeout"]:
>             req.cursor.execute("DELETE FROM Session where
> sid='"+session[0]+"'")        
> 
>         
> 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])
>         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)
> 8<---------------------------------------------------------------------
> 
> -----Oorspronkelijk bericht-----
> Van: mod_python-bounces at modpython.org
> [mailto:mod_python-bounces at modpython.org] Namens Martijn Moeling
> Verzonden: Monday, November 27, 2006 12:08 PM
> Aan: mod_python at modpython.org
> Onderwerp: [mod_python] Session Storage : memory, file, dbm....Mysql?
> 
> Hi,
> 
> I am building an application framework (yes!) with very specific needs.
> One of the main problems I run into is session management, I'll explain:
> 
> My application (Running on Fedora) Is prepared for multiple front-end
> servers communicating on an Internal backbone to a database server.
> Think of it as some sort of web based Citrix able to run on all browsers
> without the need of client-side software installation. Fully
> programmable in python (even the front-end) and if the time gets there
> even Visual. So build a browser based application within an application
> with central storage and management. Mod Python is used to implement a
> part of an OS if you wish to call it that way.
> 
> The front ends will be Apache servers with mod_python connected to the
> Internet using round-robin DNS (Multiple ip addresses for one Host), In
> theory a PC will do a DNS lookup and get the address of one of the
> front-end, this PC will keep this address until the TTL makes it expire
> in the DNS caches along the way, there is no problem since each session
> will be served by the same front end.
> 
> But I need to find a way to get the session information into the MySQL
> database in the backend server to enable central monitoring and inter
> user communications etc. (think of a Messenger online userlist as an
> example)
> 
> I can of course write stuff to maintain this sort of data in the MySQL
> database but what if the session ends other than a user logging out
> nicely (broken connection, browser close etc.)
> 
> It would be nice to have a MySQLsession object, an extra parameter could
> be added like a MySQLdb cursor object, or am I wrong and are sessions
> maintained by Apache (since modpython does not seem to keep track of
> Session closing), or is there any way to "list" active sessions from
> within modpython, so I can let the backend server send an http request
> to the front-end and doing something like:
> http://frontend1/getsessionlist which returns a comma separated list of
> active session id's, so the stale session records in the database can be
> removed.
> 
> I have been researching Session.py
> Where I interestingly found:
> (from def dbm_cleanup(data):)
> 
> If (time.time() - dict[_accessed]) > dict["_timeout]:
> 	old.append(key)
> ..
> ..
> ..
> For key in old:
> 	Del db[key]
> 
> If I understand this right, this means that this is done to see if the
> session is ended right? So It I alter Session.py I could make my own
> MySQL Session right?
> 
> Would there be anyone else Interested in a MySQLSession object and what
> do I need to take into account when modifying it?
> 
> 
> Please feel free to comment on any of this,
> 
> Martijn Moeling
> 
> _______________________________________________
> Mod_python mailing list
> Mod_python at modpython.org
> http://mailman.modpython.org/mailman/listinfo/mod_python
> 
> _______________________________________________
> Mod_python mailing list
> Mod_python at modpython.org
> http://mailman.modpython.org/mailman/listinfo/mod_python


More information about the Mod_python mailing list