org.mortbay.terracotta.servlet
Class TerracottaSessionManager
java.lang.Object
org.mortbay.component.AbstractLifeCycle
org.mortbay.jetty.servlet.AbstractSessionManager
org.mortbay.terracotta.servlet.TerracottaSessionManager
- All Implemented Interfaces:
- Runnable, LifeCycle, SessionManager
public class TerracottaSessionManager
- extends AbstractSessionManager
- implements Runnable
A specialized SessionManager to be used with 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, 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
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 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
newLockId(String)
.
- See Also:
TerracottaSessionIdManager
Fields inherited from class org.mortbay.jetty.servlet.AbstractSessionManager |
__distantFuture, _context, _dftMaxIdleSecs, _httpOnly, _loader, _maxCookieAge, _maxSessions, _minSessions, _nodeIdInSessionId, _refreshCookieAge, _secureCookies, _sessionAttributeListeners, _sessionCookie, _sessionDomain, _sessionHandler, _sessionIdManager, _sessionListeners, _sessionPath, _sessionURL, _sessionURLPrefix |
Methods inherited from class org.mortbay.jetty.servlet.AbstractSessionManager |
addEventListener, addSession, clearEventListeners, getClusterId, getHttpOnly, getHttpSession, getIdManager, getMaxCookieAge, getMaxInactiveInterval, getMaxSessions, getMetaManager, getMinSessions, getNodeId, getRefreshCookieAge, getSecureCookies, getSessionCookie, getSessionCookie, getSessionDomain, getSessionHandler, getSessionPath, getSessionURL, getSessionURLPrefix, isNodeIdInSessionId, isUsingCookies, isValid, newHttpSession, removeEventListener, removeSession, removeSession, resetStats, setHttpOnly, setIdManager, setMaxCookieAge, setMaxInactiveInterval, setMetaManager, setNodeIdInSessionId, setRefreshCookieAge, setSecureCookies, setSessionCookie, setSessionDomain, setSessionHandler, setSessionPath, setSessionURL, setUsingCookies |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
TerracottaSessionManager
public TerracottaSessionManager()
doStart
public void doStart()
throws Exception
- Overrides:
doStart
in class AbstractSessionManager
- Throws:
Exception
doStop
public void doStop()
throws Exception
- Overrides:
doStop
in class AbstractSessionManager
- Throws:
Exception
run
public void run()
- Specified by:
run
in interface Runnable
enter
public void enter(Request request)
enter
protected void enter(String clusterId)
tryEnter
protected boolean tryEnter(String clusterId)
exit
public void exit(Request request)
exit
protected void exit(String clusterId)
addSession
protected void addSession(AbstractSessionManager.Session session)
- Specified by:
addSession
in class AbstractSessionManager
access
public Cookie access(HttpSession session,
boolean secure)
- Description copied from interface:
SessionManager
- Called by the
SessionHandler
when a session is access by a request
- Specified by:
access
in interface SessionManager
- Overrides:
access
in class AbstractSessionManager
- Returns:
- Cookie If non null, this cookie should be set on the response to either migrate
the session or to refresh a cookie that may expire.
complete
public void complete(HttpSession session)
- Description copied from interface:
SessionManager
- Called by the
SessionHandler
when a reqeuest is not longer
handling a session. Not this includes new sessions, so there may not
be a matching call to #access(HttpSession)
.
- Specified by:
complete
in interface SessionManager
- Overrides:
complete
in class AbstractSessionManager
removeSession
protected void removeSession(String clusterId)
- Specified by:
removeSession
in class AbstractSessionManager
setScavengePeriodMs
public void setScavengePeriodMs(long ms)
getScavengePeriodMs
public long getScavengePeriodMs()
getSession
public AbstractSessionManager.Session getSession(String clusterId)
- Description copied from class:
AbstractSessionManager
- Get a known existingsession
- Specified by:
getSession
in class AbstractSessionManager
- Parameters:
clusterId
- The session ID in the cluster, stripped of any worker name.
- Returns:
- A Session or null if none exists.
newLockId
protected String newLockId(String clusterId)
getSessionMap
public Map getSessionMap()
- Specified by:
getSessionMap
in class AbstractSessionManager
getSessions
public int getSessions()
- Specified by:
getSessions
in class AbstractSessionManager
newSession
protected org.mortbay.terracotta.servlet.TerracottaSessionManager.Session newSession(HttpServletRequest request)
- Description copied from class:
AbstractSessionManager
- Create a new session instance
- Specified by:
newSession
in class AbstractSessionManager
- Returns:
invalidateSessions
protected void invalidateSessions()
- Specified by:
invalidateSessions
in class AbstractSessionManager
Copyright © 1995-2009 Mort Bay Consulting. All Rights Reserved.