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
|