Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-10.0.x
This commit is contained in:
commit
e789cd6834
|
@ -616,12 +616,10 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
|
||||||
{
|
{
|
||||||
//get the session, if its not in memory, this will load it
|
//get the session, if its not in memory, this will load it
|
||||||
Session session = get(id);
|
Session session = get(id);
|
||||||
|
|
||||||
|
|
||||||
//Always delete it from the backing data store
|
//Always delete it from the backing data store
|
||||||
if (_sessionDataStore != null)
|
if (_sessionDataStore != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
boolean dsdel = _sessionDataStore.delete(id);
|
boolean dsdel = _sessionDataStore.delete(id);
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("Session {} deleted in session data store {}",id, dsdel);
|
if (LOG.isDebugEnabled()) LOG.debug("Session {} deleted in session data store {}",id, dsdel);
|
||||||
}
|
}
|
||||||
|
@ -635,10 +633,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
|
||||||
return doDelete(id);
|
return doDelete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.SessionCache#checkExpiration(Set)
|
* @see org.eclipse.jetty.server.session.SessionCache#checkExpiration(Set)
|
||||||
|
|
|
@ -116,7 +116,6 @@ public class Session implements SessionHandler.SessionIf
|
||||||
public class SessionInactivityTimer
|
public class SessionInactivityTimer
|
||||||
{
|
{
|
||||||
protected final CyclicTimeout _timer;
|
protected final CyclicTimeout _timer;
|
||||||
protected long _msec = -1;
|
|
||||||
|
|
||||||
public SessionInactivityTimer()
|
public SessionInactivityTimer()
|
||||||
{
|
{
|
||||||
|
@ -127,31 +126,45 @@ public class Session implements SessionHandler.SessionIf
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Timer expired for session {}", getId());
|
LOG.debug("Timer expired for session {}", getId());
|
||||||
getSessionHandler().sessionInactivityTimerExpired(Session.this);
|
long now = System.currentTimeMillis();
|
||||||
|
//handle what to do with the session after the timer expired
|
||||||
|
getSessionHandler().sessionInactivityTimerExpired(Session.this, now);
|
||||||
|
try (Lock lock = Session.this.lock())
|
||||||
|
{
|
||||||
|
//grab the lock and check what happened to the session: if it didn't get evicted and
|
||||||
|
//it hasn't expired, we need to reset the timer
|
||||||
|
if (Session.this.isResident() && Session.this.getRequests() <= 0 && Session.this.isValid() && !Session.this.isExpiredAt(now))
|
||||||
|
{
|
||||||
|
//session wasn't expired or evicted, we need to reset the timer
|
||||||
|
SessionInactivityTimer.this.schedule(Session.this.calculateInactivityTimeout(now));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ms the timeout to set; -1 means that the timer will not be
|
* For backward api compatibility only.
|
||||||
* scheduled
|
* @see #schedule(long)
|
||||||
*/
|
*/
|
||||||
public void setTimeout(long ms)
|
@Deprecated
|
||||||
|
public void schedule ()
|
||||||
{
|
{
|
||||||
_msec = ms;
|
schedule(calculateInactivityTimeout(System.currentTimeMillis()));
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Session {} timer={}ms", getId(), ms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void schedule()
|
/**
|
||||||
|
* @param time the timeout to set; -1 means that the timer will not be
|
||||||
|
* scheduled
|
||||||
|
*/
|
||||||
|
public void schedule (long time)
|
||||||
{
|
{
|
||||||
if (_msec > 0)
|
if (time >= 0)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("(Re)starting timer for session {} at {}ms", getId(), _msec);
|
LOG.debug("(Re)starting timer for session {} at {}ms", getId(), time);
|
||||||
_timer.schedule(_msec, TimeUnit.MILLISECONDS);
|
_timer.schedule(time, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -279,9 +292,15 @@ public class Session implements SessionHandler.SessionIf
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Session {} complete, active requests={}", getId(), _requests);
|
LOG.debug("Session {} complete, active requests={}", getId(), _requests);
|
||||||
|
|
||||||
// start the inactivity timer
|
// start the inactivity timer if necessary
|
||||||
if (_requests == 0)
|
if (_requests == 0)
|
||||||
_sessionInactivityTimer.schedule();
|
{
|
||||||
|
//update the expiry time to take account of the time all requests spent inside of the
|
||||||
|
//session.
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
_sessionData.calcAndSetExpiry(now);
|
||||||
|
_sessionInactivityTimer.schedule(calculateInactivityTimeout(now));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,7 +532,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
_sessionData.setMaxInactiveMs((long) secs * 1000L);
|
_sessionData.setMaxInactiveMs((long) secs * 1000L);
|
||||||
_sessionData.calcAndSetExpiry();
|
_sessionData.calcAndSetExpiry();
|
||||||
_sessionData.setDirty(true);
|
_sessionData.setDirty(true);
|
||||||
updateInactivityTimer();
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
{
|
{
|
||||||
if (secs <= 0)
|
if (secs <= 0)
|
||||||
|
@ -524,14 +543,29 @@ public class Session implements SessionHandler.SessionIf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the inactivity timer to the smaller of the session maxInactivity (ie
|
@Deprecated
|
||||||
* session-timeout from web.xml), or the inactive eviction time.
|
public void updateInactivityTimer()
|
||||||
*/
|
|
||||||
public void updateInactivityTimer()
|
|
||||||
{
|
{
|
||||||
|
//for backward api compatibility only
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate what the session timer setting should be based on:
|
||||||
|
* the time remaining before the session expires
|
||||||
|
* and any idle eviction time configured.
|
||||||
|
* The timer value will be the lesser of the above.
|
||||||
|
*
|
||||||
|
* @param now the time at which to calculate remaining expiry
|
||||||
|
* @return the time remaining before expiry or inactivity timeout
|
||||||
|
*/
|
||||||
|
public long calculateInactivityTimeout (long now)
|
||||||
|
{
|
||||||
|
long time = 0;
|
||||||
|
|
||||||
try (Lock lock = _lock.lock())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
|
long remaining = _sessionData.getExpiry() - now;
|
||||||
long maxInactive = _sessionData.getMaxInactiveMs();
|
long maxInactive = _sessionData.getMaxInactiveMs();
|
||||||
int evictionPolicy = getSessionHandler().getSessionCache().getEvictionPolicy();
|
int evictionPolicy = getSessionHandler().getSessionCache().getEvictionPolicy();
|
||||||
|
|
||||||
|
@ -541,7 +575,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
if (evictionPolicy < SessionCache.EVICT_ON_INACTIVITY)
|
if (evictionPolicy < SessionCache.EVICT_ON_INACTIVITY)
|
||||||
{
|
{
|
||||||
// we do not want to evict inactive sessions
|
// we do not want to evict inactive sessions
|
||||||
_sessionInactivityTimer.setTimeout(-1);
|
time = -1;
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Session {} is immortal && no inactivity eviction", getId());
|
LOG.debug("Session {} is immortal && no inactivity eviction", getId());
|
||||||
}
|
}
|
||||||
|
@ -549,7 +583,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
{
|
{
|
||||||
// sessions are immortal but we want to evict after
|
// sessions are immortal but we want to evict after
|
||||||
// inactivity
|
// inactivity
|
||||||
_sessionInactivityTimer.setTimeout(TimeUnit.SECONDS.toMillis(evictionPolicy));
|
time = TimeUnit.SECONDS.toMillis(evictionPolicy);
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Session {} is immortal; evict after {} sec inactivity", getId(), evictionPolicy);
|
LOG.debug("Session {} is immortal; evict after {} sec inactivity", getId(), evictionPolicy);
|
||||||
}
|
}
|
||||||
|
@ -559,31 +593,33 @@ public class Session implements SessionHandler.SessionIf
|
||||||
// sessions are not immortal
|
// sessions are not immortal
|
||||||
if (evictionPolicy == SessionCache.NEVER_EVICT)
|
if (evictionPolicy == SessionCache.NEVER_EVICT)
|
||||||
{
|
{
|
||||||
// timeout is just the maxInactive setting
|
// timeout is the time remaining until its expiry
|
||||||
_sessionInactivityTimer.setTimeout(_sessionData.getMaxInactiveMs());
|
time = (remaining > 0 ? remaining : 0);
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Session {} no eviction", getId());
|
LOG.debug("Session {} no eviction", getId());
|
||||||
}
|
}
|
||||||
else if (evictionPolicy == SessionCache.EVICT_ON_SESSION_EXIT)
|
else if (evictionPolicy == SessionCache.EVICT_ON_SESSION_EXIT)
|
||||||
{
|
{
|
||||||
// session will not remain in the cache, so no timeout
|
// session will not remain in the cache, so no timeout
|
||||||
_sessionInactivityTimer.setTimeout(-1);
|
time = -1;
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Session {} evict on exit", getId());
|
LOG.debug("Session {} evict on exit", getId());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// want to evict on idle: timer is lesser of the session's
|
// want to evict on idle: timer is lesser of the session's
|
||||||
// maxInactive and eviction timeout
|
// expiration remaining and the time to evict
|
||||||
_sessionInactivityTimer.setTimeout(Math.min(maxInactive, TimeUnit.SECONDS.toMillis(evictionPolicy)));
|
time = (remaining > 0 ? (Math.min(maxInactive, TimeUnit.SECONDS.toMillis(evictionPolicy))) : 0);
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Session {} timer set to lesser of maxInactive={} and inactivityEvict={}", getId(), maxInactive, evictionPolicy);
|
LOG.debug("Session {} timer set to lesser of maxInactive={} and inactivityEvict={}", getId(), maxInactive, evictionPolicy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see javax.servlet.http.HttpSession#getMaxInactiveInterval()
|
* @see javax.servlet.http.HttpSession#getMaxInactiveInterval()
|
||||||
*/
|
*/
|
||||||
|
@ -963,16 +999,6 @@ public class Session implements SessionHandler.SessionIf
|
||||||
return _lock.lock();
|
return _lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* Grab the lock on the session if it isn't locked already
|
|
||||||
*
|
|
||||||
* @return the lock
|
|
||||||
*/
|
|
||||||
public Lock lockIfNotHeld()
|
|
||||||
{
|
|
||||||
return _lock.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
|
@ -1132,13 +1158,14 @@ public class Session implements SessionHandler.SessionIf
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* @param resident
|
||||||
|
*/
|
||||||
public void setResident(boolean resident)
|
public void setResident(boolean resident)
|
||||||
{
|
{
|
||||||
_resident = resident;
|
_resident = resident;
|
||||||
|
|
||||||
if (_resident)
|
if (!_resident)
|
||||||
updateInactivityTimer();
|
|
||||||
else
|
|
||||||
_sessionInactivityTimer.destroy();
|
_sessionInactivityTimer.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1372,6 +1372,17 @@ public class SessionHandler extends ScopedHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #sessionInactivityTimerExpired(Session, long)
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void sessionInactivityTimerExpired (Session session)
|
||||||
|
{
|
||||||
|
//for backwards compilation compatibility only
|
||||||
|
sessionInactivityTimerExpired(session, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* Each session has a timer that is configured to go off
|
* Each session has a timer that is configured to go off
|
||||||
|
@ -1379,20 +1390,28 @@ public class SessionHandler extends ScopedHandler
|
||||||
* configurable amount of time, or the session itself
|
* configurable amount of time, or the session itself
|
||||||
* has passed its expiry.
|
* has passed its expiry.
|
||||||
*
|
*
|
||||||
|
* If it has passed its expiry, then we will mark it for
|
||||||
|
* scavenging by next run of the HouseKeeper; if it has
|
||||||
|
* been idle longer than the configured eviction period,
|
||||||
|
* we evict from the cache.
|
||||||
|
*
|
||||||
|
* If none of the above are true, then the System timer
|
||||||
|
* is inconsistent and the caller of this method will
|
||||||
|
* need to reset the timer.
|
||||||
|
*
|
||||||
* @param session the session
|
* @param session the session
|
||||||
|
* @param now the time at which to check for expiry
|
||||||
*/
|
*/
|
||||||
public void sessionInactivityTimerExpired (Session session)
|
public void sessionInactivityTimerExpired (Session session, long now)
|
||||||
{
|
{
|
||||||
if (session == null)
|
if (session == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
//check if the session is:
|
//check if the session is:
|
||||||
//1. valid
|
//1. valid
|
||||||
//2. expired
|
//2. expired
|
||||||
//3. idle
|
//3. idle
|
||||||
boolean expired = false;
|
try (Lock lock = session.lock())
|
||||||
try (Lock lock = session.lockIfNotHeld())
|
|
||||||
{
|
{
|
||||||
if (session.getRequests() > 0)
|
if (session.getRequests() > 0)
|
||||||
return; //session can't expire or be idle if there is a request in it
|
return; //session can't expire or be idle if there is a request in it
|
||||||
|
@ -1402,27 +1421,27 @@ public class SessionHandler extends ScopedHandler
|
||||||
|
|
||||||
if (!session.isValid())
|
if (!session.isValid())
|
||||||
return; //do nothing, session is no longer valid
|
return; //do nothing, session is no longer valid
|
||||||
|
|
||||||
if (session.isExpiredAt(System.currentTimeMillis()) && session.getRequests() <=0)
|
|
||||||
expired = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expired)
|
if (session.isExpiredAt(now))
|
||||||
{
|
|
||||||
//instead of expiring the session directly here, accumulate a list of
|
|
||||||
//session ids that need to be expired. This is an efficiency measure: as
|
|
||||||
//the expiration involves the SessionDataStore doing a delete, it is
|
|
||||||
//most efficient if it can be done as a bulk operation to eg reduce
|
|
||||||
//roundtrips to the persistent store. Only do this if the HouseKeeper that
|
|
||||||
//does the scavenging is configured to actually scavenge
|
|
||||||
if (_sessionIdManager.getSessionHouseKeeper() != null && _sessionIdManager.getSessionHouseKeeper().getIntervalSec() > 0)
|
|
||||||
{
|
{
|
||||||
_candidateSessionIdsForExpiry.add(session.getId());
|
//instead of expiring the session directly here, accumulate a list of
|
||||||
if (LOG.isDebugEnabled())LOG.debug("Session {} is candidate for expiry", session.getId());
|
//session ids that need to be expired. This is an efficiency measure: as
|
||||||
|
//the expiration involves the SessionDataStore doing a delete, it is
|
||||||
|
//most efficient if it can be done as a bulk operation to eg reduce
|
||||||
|
//roundtrips to the persistent store. Only do this if the HouseKeeper that
|
||||||
|
//does the scavenging is configured to actually scavenge
|
||||||
|
if (_sessionIdManager.getSessionHouseKeeper() != null && _sessionIdManager.getSessionHouseKeeper().getIntervalSec() > 0)
|
||||||
|
{
|
||||||
|
_candidateSessionIdsForExpiry.add(session.getId());
|
||||||
|
if (LOG.isDebugEnabled())LOG.debug("Session {} is candidate for expiry", session.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//possibly evict the session
|
||||||
|
_sessionCache.checkInactiveSession(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
_sessionCache.checkInactiveSession(session); //if inactivity eviction is enabled the session will be deleted from the cache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue