Skip to content

Commit

Permalink
Fixed issue 706, session sweep bug.
Browse files Browse the repository at this point in the history
  • Loading branch information
yuseitahara committed Sep 12, 2006
1 parent 9c5a308 commit 5e4d915
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions session.py
Expand Up @@ -137,6 +137,51 @@ def __getitem__(self, pkg_id):
>>> sdc['client_id'].lastAccessTime == lastAccessTime
True
Next, we test session expiration functionality beyond transactions.
>>> import transaction
>>> from ZODB.DB import DB
>>> from ZODB.DemoStorage import DemoStorage
>>> sdc = PersistentSessionDataContainer()
>>> sdc.timeout = 60
>>> sdc.resolution = 3
>>> db = DB(DemoStorage('test_storage'))
>>> c = db.open()
>>> c.root()['sdc'] = sdc
>>> sdc['pkg_id'] = sd = SessionData()
>>> sd['name'] = 'bob'
>>> transaction.commit()
Access immediately. the data should be accessible.
>>> c.root()['sdc']['pkg_id']['name']
'bob'
Change the clock time and stale the session data.
>>> sdc = c.root()['sdc']
>>> sd = sdc['pkg_id']
>>> sd.lastAccessTime = sd.lastAccessTime - 64
>>> sdc._v_last_sweep = sdc._v_last_sweep - 4
>>> transaction.commit()
The data should be garbage collected.
>>> c.root()['sdc']['pkg_id']['name']
Traceback (most recent call last):
[...]
KeyError: 'pkg_id'
Then abort transaction and access the same data again.
The previous GC was cancelled, but deadline is over.
The data should be garbage collected again.
>>> transaction.abort()
>>> c.root()['sdc']['pkg_id']['name']
Traceback (most recent call last):
[...]
KeyError: 'pkg_id'
"""
if self.timeout == 0:
return IterableUserDict.__getitem__(self, pkg_id)
Expand All @@ -146,8 +191,21 @@ def __getitem__(self, pkg_id):
# TODO: When scheduler exists, sweeping should be done by
# a scheduled job since we are currently busy handling a
# request and may end up doing simultaneous sweeps

# If transaction is aborted after sweep. _v_last_sweep keep
# incorrect sweep time. So when self.data is ghost, revert the time
# to the previous _v_last_sweep time(_v_old_sweep).
if self.data._p_state < 0:
try:
self._v_last_sweep = self._v_old_sweep
del self._v_old_sweep
except AttributeError:
pass

if self._v_last_sweep + self.resolution < now:
self.sweep()
if getattr(self, '_v_old_sweep', None) is None:
self._v_old_sweep = self._v_last_sweep
self._v_last_sweep = now

rv = IterableUserDict.__getitem__(self, pkg_id)
Expand Down

0 comments on commit 5e4d915

Please sign in to comment.