[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