changeset 5576:6b94d284ad11

avoid writing key/value to session dict if value doesn't change
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Tue, 23 Feb 2010 03:41:30 +0100
parents 17cf01154e12
children 092ce221f03a
files MoinMoin/user.py MoinMoin/web/session.py
diffstat 2 files changed, 24 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/user.py	Tue Feb 23 02:29:09 2010 +0100
+++ b/MoinMoin/user.py	Tue Feb 23 03:41:30 2010 +0100
@@ -891,6 +891,7 @@
                 pagename = self._interWikiName(pagename)
 
             trail = self._request.session.get('trail', [])
+            trail_current = trail[:]
 
             # Don't append tail to trail ;)
             if trail and trail[-1] == pagename:
@@ -901,7 +902,10 @@
             pagename_stripped = pagename.strip()
             if pagename_stripped:
                 trail.append(pagename_stripped)
-            self._request.session['trail'] = trail[-self._cfg.trail_size:]
+            trail = trail[-self._cfg.trail_size:]
+            if trail != trail_current:
+                # we only modify the session if we have something different:
+                self._request.session['trail'] = trail
 
     def getTrail(self):
         """ Return list of recently visited pages.
--- a/MoinMoin/web/session.py	Tue Feb 23 02:29:09 2010 +0100
+++ b/MoinMoin/web/session.py	Tue Feb 23 03:41:30 2010 +0100
@@ -319,6 +319,16 @@
         store.delete(session)
 
     def finalize(self, request, session):
+        def update_session(key, val):
+            """ put key/val into session, avoid writing if it is unchanged """
+            try:
+                current_val = session[key]
+            except KeyError:
+                session[key] = val
+            else:
+                if val != current_val:
+                    session[key] = val
+
         if request.user.auth_method == 'setuid':
             userobj = request._setuid_real_user
             setuid = request.user.id
@@ -333,11 +343,11 @@
         # which is usually not needed and not recommended:
         cookie_path = cfg.cookie_path or '/'
         if userobj and userobj.valid:
-            session['user.id'] = userobj.id
-            session['user.auth_method'] = userobj.auth_method
-            session['user.auth_attribs'] = userobj.auth_attribs
+            update_session('user.id', userobj.id)
+            update_session('user.auth_method', userobj.auth_method)
+            update_session('user.auth_attribs', userobj.auth_attribs)
             if setuid:
-                session['setuid'] = setuid
+                update_session('setuid', setuid)
             elif 'setuid' in session:
                 del session['setuid']
             logging.debug("after auth: storing valid user into session: %r" % userobj.name)
@@ -351,7 +361,8 @@
 
         cookie_lifetime = _get_session_lifetime(request, userobj)
         if cookie_lifetime:
-            cookie_expires = time.time() + cookie_lifetime
+            # we use 60s granularity, so we don't trigger session storage updates too often
+            cookie_expires = int(time.time() / 60) * 60 + cookie_lifetime
             # a secure cookie is not transmitted over unsecure connections:
             cookie_secure = (cfg.cookie_secure or  # True means: force secure cookies
                              cfg.cookie_secure is None and request.is_secure)  # None means: https -> secure cookie
@@ -361,18 +372,15 @@
                                path=cookie_path, domain=cfg.cookie_domain,
                                secure=cookie_secure, httponly=cfg.cookie_httponly)
 
+            # add some info about expiry to the sessions, so we can purge them:
+            update_session('expires', cookie_expires)
+
             if ((not userobj.valid and not session.new  # anon users with a cookie (not first request)
                  or
                  userobj.valid) # logged-in users, even if THIS was the first request (no cookie yet)
                                 # XXX if UA doesn't support cookies, this creates 1 session file per request
                 and
                 session.should_save): # only if we really have something to save
-                # add some info about expiry to the sessions, so we can purge them:
-                session['expires'] = cookie_expires
-                # note: currently, every request of a logged-in user will save
-                # the session, even when always requesting same page.
-                # No big deal, as we store the trail into session and that
-                # likely changes with every request anyway.
                 store = self._store_get(request)
                 logging.debug("saving session: %r" % session)
                 store.save(session)