[mod_python] For what session locking is? Do i need it while using MySQL?

Jim Gallacher jpg at jgassociates.ca
Fri Aug 11 12:29:59 EDT 2006


It mostly looks ok, but I really don't have a lot of spare time to audit
a new  session handling implementation. That's one of the disadvantages
of writing things from scratch I guess.

Jim


Norman Tindall wrote:
> Hello Jim,
>    So far by now i already wrote raw working code,
>    I know that it can invalidate a valid session, i have read this
>    about 2 thread A and B.. for now i can stand with this..
>    Will make something like transactions in future..
> 
>    The question is: Is Session based on this class realy locked?
> 
> ##############################################
> class MySQLSession(object):
> 
>     def __init__(self, req, sid=0, secret=None, timeout=0, create_new = 0 ):
>         self._lock = 1
>         self._locked = 0
>         self.cursors = req.cursors
>         self._req, self._sid  = req, sid
>         if self._sid: 
>             self._create_new = 1
>         else:
>             self._create_new = create_new
>         self._new = 0
>         self._created = 0
>         self._accessed = 0
>         self._timeout = 1000000
>         self._invalid = 0
> 
>         self.data = {}
> 
>         if secret: self._secret = secret
>         else: self._secret = "secret007"
>         self.session_cookie_name = "OxSess"
> 
> 
>         if not self._sid:
>             cookies = Cookie.get_cookies(req, Class=Cookie.SignedCookie, secret=self._secret)
>             if cookies.has_key(self.session_cookie_name):
>                 self._sid = cookies[ self.session_cookie_name ].value
>         
>         if self._sid:
>             if not _check_sid(self._sid):
>                 self._req.log_error("mod_python.Session warning: The session id contains invalid characters",
>                         apache.APLOG_WARNING)
>                 raise apache.SERVER_RETURN, apache.HTTP_INTERNAL_SERVER_ERROR
> 
>         ############ CLEANUP ##############
>         if random.randint(1, CLEANUP_CHANCE) == 1:
>             self.cleanup()
>         ###################################
> 
>         if self._create_new:
>             if self._sid:
>                 self.delete() # del old one
>                 self.unlock() # unlock old one
>                 self.create_new_sess()
>             else:
>                 self.create_new_sess()
> 
>         else:
>             if self._sid:
>                 # attempt to load ourselves
>                 self.lock()
>                 if self.load():
>                     self._new = 0
>             else:
>                 # no sid no session
>                 return None
>                 
>         
> 
>     def create_new_sess(self):
>         self._sid = _new_sid(self._req)
>         self.lock()  # lock new sid
>         Cookie.add_cookie(self._req, self.make_cookie())
>         self._created = time.time()
>         self._accessed = self._created
>         self._new = 1
> 
> # LOCK
> 
>     def lock(self):
>         if self._lock:
>             _apache._global_lock(self._req.server, self._sid)
>             self._locked = 1
>             self._req.register_cleanup(unlock_session_cleanup, self)
> 
> # UNLOCK
> 
>     def unlock(self):
>         if self._lock and self._locked:
>             _apache._global_unlock(self._req.server, self._sid)
>             self._locked = 0
> 
> 
>     def load(self):
>         # selecting only alive sessions
>         self.cursors['c'].execute(
>         """select UNIX_TIMESTAMP() as ACCESS_TIME,TIMEOUT,CREATE_DATE,DATA from sessions where SESS_MD = %s and 
>         DATE_ADD(ACCESS_TIME, INTERVAL TIMEOUT SECOND) > CURRENT_TIMESTAMP()""", (self._sid,) )
>         row = self.cursors['c'].fetchone()
> 
>         if row is not None:
>             # assigning attributes    
>             self._accessed = row[0]
>             self._timeout = row[1]
>             self._created = row[2]
>             self.data = cPickle.loads(row[3])
>             return 1
>         else:
>             return 0
> 
>     def save(self):
>         if not self._invalid:
> 
>             self.cursors['c'].execute("""replace into sessions 
>             (SESS_MD,ACCESS_TIME,TIMEOUT,CREATE_DATE,DATA) values (%s,NULL,%s,FROM_UNIXTIME(%s),%s)""",
>             (self._sid,self._timeout,self._created, cPickle.dumps(self.data) ))
> 
> 
>     def invalidate(self):
>         c = self.make_cookie()
>         c.expires = 0
>         Cookie.add_cookie(self._req, c)
>         self.delete()
>         self._invalid = 1
> 
>     def make_cookie(self):
>         c = Cookie.SignedCookie(self.session_cookie_name, self._sid, secret=self._secret)
>         c.path = '/'
>         return c
> 
>     def cleanup(self):
>         self.cursors['c'].execute("delete from sessions where DATE_ADD(ACCESS_TIME, INTERVAL TIMEOUT SECOND) < CURRENT_TIMESTAMP()")
> 
>     def delete(self):
>         self.cursors['c'].execute("delete from sessions where SESS_MD=%s", (self._sid,))
>         # erasing attributes !
> 
> #######
>     def is_new(self):
>         return not not self._new
> 
>     def id(self):
>         return self._sid
> 
>     def created(self):
>         return self._created
> 
>     def last_accessed(self):
>         return self._accessed
> 
>     def timeout(self):
>         return self._timeout
> 
>     def set_timeout(self, secs):
>         self._timeout = secs
> 
>     def __del__(self):
>         self.unlock()
> 
> 
> def unlock_session_cleanup(sess):
>     sess.unlock()
> 
> 
> 
> 
> 



More information about the Mod_python mailing list