erracotta.org">Terracotta.
IMPLEMENTATION NOTES
Requirements
This implementation of the session management requires J2SE 5 or superior.
Use of Hashtable
In Terracotta, collections classes are
logically managed and we need two levels of locking: a local locking to handle concurrent requests on the same node and a distributed locking to handle concurrent requests on different nodes. Natively synchronized classes such as Hashtable fit better than synchronized wrappers obtained via, for example, {@link Collections#synchronizedMap(Map)}. This is because Terracotta may replay the method call on the inner unsynchronized collection without invoking the external wrapper, so the synchronization will be lost. Natively synchronized collections does not have this problem.
Use of Hashtable as a Set
There is no natively synchronized Set implementation, so we use Hashtable instead, see {@link TerracottaSessionIdManager}. However, we don't map the session id to itself, because Strings are treated specially by Terracotta, causing more traffic to the Terracotta server. Instead we use the same pattern used in the implementation of
java.util.HashSet
: use a single shared object to indicate the presence of a key. This is necessary since Hashtable does not allow null values.
Sessions expiration map
In order to scavenge expired sessions, we need a way to know if they are expired. This information is normally held in the session itself via the
lastAccessedTime
property. However, we would need to iterate over all sessions to check if each one is expired, and this migrates all sessions to the node, causing a lot of unneeded traffic between nodes and the Terracotta server. To avoid this, we keep a separate map from session id to expiration time, so we only need to migrate all the expirations times to see if a session is expired or not.
Update of lastAccessedTime
As a performance improvement, the lastAccessedTime is updated only periodically, and not every time a request enters a node. This optimization allows applications that have frequent requests but less frequent accesses to the session to perform better, because the traffic between the node and the Terracotta server is reduced. The update period is the scavenger period, see {@link Session#access(long)}.
Terracotta lock id
The Terracotta lock id is based on the session id, but this alone is not sufficient, as there may be two sessions with the same id for two different contexts. So we need session id and context path. However, this also is not enough, as we may have the rare case of the same webapp mapped to two different virtual hosts, and each virtual host must have a different session object. Therefore the lock id we need to use is a combination of session id, context path and virtual host, see {@link #newLockId(String)}.
@see TerracottaSessionIdManager