Product README
Overview
This product contains two new implementations of the "session manager"
API used in Zope's "core sessioning" machinery: it is intended as a
replacement for the implementation supplied in the Transience product
(TransientObjectContainer).
Linked-List SDC
The primary implementation, (see sessiondata.SessionDataContainer)
stores session objects (see sessiondata.SessionDataObject) in
a singly-linked list (see 'linkedlist) of "buckets", where each
bucket is a tuple representing the creation timestamp of the tuple,
and the OOBTree containing the SDOs accessed during that time period:
+======================+ +============+ ?
| SessionDataContainer | head | ListNode |------+
| |-----------| | |
| | 1 | |<-----+
+======================+ +============+ next
|
ob | 1
+=============+
| tuple |
| |
| |
+=============+
|
+----------+---------+
| |
+=============+ +=============+
| timestamp | | OOBTree |
| | | |
| | | |
+=============+ +=============+
Searching the Linked-List SDC
When searching for a session object, the session first gets the
current head bucket. If that head is older than the SDC's period,
the SDC creates a new bucket and pushes it onto the list as the new
head (its next is the old head).
The SDC then iterates through the list of buckets, until one of the following is true:
- The
OOBTreein the bucket contains the key. In this case, the corresponding SDO is copied forward into the "head" bucket and returned. - The
timestampin the current bucket is older than the SDC's 'timeout'; in this case, the SDC truncates the list, and then performs housekeeping (see "Linked-List Housekeeping" below) on the truncated tail of the list. - The list ends before finding the key.
In either of the last two cases, the SDC creates a new SDO for the key.
If the SDC is marked as lazy, it sets a callback to copy the new SDO
into the "head" bucket's OOBTree when the transaction commits, if the
SDO has been modified. If the SDC is not lazy, it copies the new
SDO into the head bucket immediately. In either case, the SDC also
calls a utility (if one is registered for ISessionBeginNotifier),
passing the new SDO.
Linked-List SDC Housekeeping
After discovering that a given bucket in its list represents an "expired"
timeslice, the SDC truncates the list, setting the next attribute of
the oldest valid node to None. The SDC then processes the expired
remainder as follows:
- It first constructs a set,
seen, containing the keys stored in the "valid" nodes. - For each expired node, it checks the keys in the node's OOBTree;
for each key, if that key is not already seen, it calls a utility
(if one is registered for the
ISessionEndNotifierinterface), passing the doomed SDO; it then adds the key to the "seen" set.
Linked-List SDC Conflict Resolution
Near-simultaneous transactions may attempt to modify the linked list, either by pushing a new head bucket, or else by truncating the list at its oldest "valid" bucket.
TODO: explain the resolution strategy
- First, fail for conflicts on the period or timeout.
- Next, if either the
newversion or thecommittedversion has obsoleted theoldversion, fail. - Finally, splice together the inserted nodes from the
newverision and inserted nodes from thecommittedversion (truncating the latter, if necessary).
Linked-List Serialization
In order to minimize the size of the pickle storing the linked list, the list class serializes itself as a native Python list of pointers to the objects.