[Checkins] SVN: lovely.session/trunk/ Correctly implemented timeout behavior of session data. Thanks to Chris

Stephan Richter srichter at cosmos.phy.tufts.edu
Wed Nov 26 19:49:59 EST 2008


Log message for revision 93376:
  Correctly implemented timeout behavior of session data. Thanks to Chris 
  Traynor to work through this.
  
  

Changed:
  U   lovely.session/trunk/CHANGES.txt
  U   lovely.session/trunk/src/lovely/session/README.txt
  U   lovely.session/trunk/src/lovely/session/memcached.py

-=-
Modified: lovely.session/trunk/CHANGES.txt
===================================================================
--- lovely.session/trunk/CHANGES.txt	2008-11-26 23:34:31 UTC (rev 93375)
+++ lovely.session/trunk/CHANGES.txt	2008-11-27 00:49:59 UTC (rev 93376)
@@ -5,7 +5,7 @@
 0.2.1 (unreleased)
 ------------------
 
-- ...
+- Correctly implemented timeout behavior of session data.
 
 
 0.2.0 (2008-09-25)

Modified: lovely.session/trunk/src/lovely/session/README.txt
===================================================================
--- lovely.session/trunk/src/lovely/session/README.txt	2008-11-26 23:34:31 UTC (rev 93375)
+++ lovely.session/trunk/src/lovely/session/README.txt	2008-11-27 00:49:59 UTC (rev 93376)
@@ -25,9 +25,67 @@
   >>> component.provideUtility(util, IMemcachedClient, name='session')
   >>> util.invalidateAll()
 
+
+Import the container we will use for caching tests.
+
+  >>> from lovely.session.memcached import MemCachedSessionDataContainer
+
+Timeout behavior
+~~~~~~~~~~~~~~~~
+
+We need to test the timeout capability of the container.  We can do this by simulating the passage of time while minimizing the timeout period.
+
+Create a new session data that we will cause to timeout.
+
+  >>> timeoutSessionData = MemCachedSessionDataContainer()
+  >>> timeoutSessionData.cacheName = u'session'
+  >>> timeoutSessionData.__name__ = 'MemCacheSession'
+
+  >>> timeoutSession = timeoutSessionData['mySessionId']
+  >>> timeoutSession
+  {}
+
+So we expect it is empty at this point.  Get a new session from it.
+
+  >>> timeoutData = timeoutSession['myData1']
+  >>> timeoutData
+  {}
+
+Okay, so now add some data to that session.
+
+  >>> timeoutData['info'] = 'stored in memcache'
+  >>> timeoutData
+  {'info': 'stored in memcache'}
+
+Now get that sessionData from the session.  It should just give it to us and the sessionData should have data.
+
+  >>> timeoutData = timeoutSession['myData1']
+  >>> timeoutData
+  {'info': 'stored in memcache'}
+
+Now simulate the effect of a timeout by forcing one.
+
+  >>> timeoutSessionData.timeout=1
+  >>> timeoutSessionData.lastAccessTime=0
+
+Now ask the sessionData for the session again.  If the timeout worked, the session will be empty.
+
+  >>> timeoutSession = timeoutSessionData['mySessionId']
+  >>> timeoutSession
+  {}
+
+Attempt to get the data from the session anyway and it will also be empty.
+
+  >>> timeoutData = timeoutSession['myData1']
+  >>> timeoutData
+  {}
+
+
+Normal memcache access
+~~~~~~~~~~~~~~~~~~~~~~
+
 Now we create a memcache session and connect it to the memcached client.
 
-  >>> from lovely.session.memcached import MemCachedSessionDataContainer
   >>> sessionData = MemCachedSessionDataContainer()
   >>> sessionData.cacheName = u'session'
 
@@ -55,7 +113,6 @@
   {'info': 'stored in memcache'}
 
 
-
 Transaction support
 ~~~~~~~~~~~~~~~~~~~
 

Modified: lovely.session/trunk/src/lovely/session/memcached.py
===================================================================
--- lovely.session/trunk/src/lovely/session/memcached.py	2008-11-26 23:34:31 UTC (rev 93375)
+++ lovely.session/trunk/src/lovely/session/memcached.py	2008-11-27 00:49:59 UTC (rev 93376)
@@ -51,6 +51,7 @@
     def __init__(self):
         self.resolution = 5*60
         self.timeout = 1 * 60 * 60
+        self.lastAccessTime = int(time.time())
 
     def get(self, key, default=None):
         return self[key]
@@ -62,7 +63,18 @@
         # getitem never fails to make sure the session uses our own PkgData
         # implementation.
         if key in self.dataManagers:
-            dm = self.dataManagers[key]
+            if int(time.time()) - self.lastAccessTime < self.timeout:
+                dm = self.dataManagers[key]
+            else:
+                del self.dataManagers[key]
+                dm = DataManager(self, key)
+                txn = transaction.manager.get()
+                txn.join(dm)
+                self.dataManagers[key] = dm
+                item = self.client.query(self._buildKey(key))
+                if item is None:
+                    item = MemCacheSessionData()
+                dm.data = item
         else:
             dm = DataManager(self, key)
             txn = transaction.manager.get()
@@ -72,6 +84,11 @@
             if item is None:
                 item = MemCacheSessionData()
             dm.data = item
+
+        now = int(time.time())
+        if self.lastAccessTime + self.resolution < now:
+            self.lastAccessTime = now
+            
         return dm.data
 
     def __setitem__(self, key, value):



More information about the Checkins mailing list