More implementation.

This commit is contained in:
Jan Bartel 2015-10-08 08:05:52 +11:00
parent fa8232d3c8
commit e2ecf7ca14
11 changed files with 465 additions and 191 deletions

View File

@ -46,6 +46,4 @@ public abstract class AbstractSessionDataStore extends AbstractLifeCycle impleme
data.setDirty(false);
}
}
}

View File

@ -29,6 +29,7 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
public abstract class AbstractSessionStore extends AbstractLifeCycle implements SessionStore
{
protected SessionDataStore _sessionDataStore;
protected StalenessStrategy _staleStrategy;
@ -78,6 +79,16 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
_sessionDataStore = sessionDataStore;
}
public StalenessStrategy getStaleStrategy()
{
return _staleStrategy;
}
public void setStaleStrategy(StalenessStrategy staleStrategy)
{
_staleStrategy = staleStrategy;
}
/**
* Get a session object.
*
@ -161,7 +172,6 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
public boolean delete(SessionKey key) throws Exception
{
boolean deleted = true;
//TODO synchronization???
if (_sessionDataStore != null)
deleted = _sessionDataStore.delete(key);
doDelete(key);
@ -170,7 +180,21 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
public boolean isStale (Session session)
{
//TODO implement (pluggable?) algorithm for deciding if memory is stale
if (_staleStrategy != null)
return _staleStrategy.isStale(session);
return false;
}
/**
* @see org.eclipse.jetty.server.session.x.SessionStore#scavenge()
*/
@Override
public void scavenge()
{
if (!isStarted())
return;
_sessionDataStore.scavenge();
}
}

View File

@ -0,0 +1,39 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session.x;
/**
* AlwaysStale
*
*
*/
public class AlwaysStaleStrategy implements StalenessStrategy
{
/**
* @see org.eclipse.jetty.server.session.x.StalenessStrategy#isStale(org.eclipse.jetty.server.session.x.Session)
*/
@Override
public boolean isStale(Session session)
{
return true;
}
}

View File

@ -29,7 +29,9 @@ import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.log.Log;
@ -182,13 +184,15 @@ public class FileSessionDataStore extends AbstractSessionDataStore
if (size>0)
{
// input stream should not be closed here
Map<String,Object> attributes = new HashMap<String,Object>();
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is);
for (int i=0; i<size;i++)
{
String key = ois.readUTF();
Object value = ois.readObject();
data.setAttribute(key,value);
attributes.put(key,value);
}
data.putAllAttributes(attributes);
}
}

View File

@ -32,11 +32,12 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.sql.DataSource;
@ -57,6 +58,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
protected int _deleteBlockSize = 10; //number of ids to include in where 'in' clause for finding long expired sessions
protected boolean _initialized = false;
protected long _lastScavengeTime = 0;
@ -321,19 +323,6 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
protected String _maxIntervalColumn = "maxInterval";
protected String _mapColumn = "map";
private String _insertSession;
private String _deleteSession;
private String _updateSession;
private String _updateSessionNode;
private String _updateSessionAccessTime;
private String _selectBoundedExpiredSessions;
private String _selectExpiredSessions;
protected void setDatabaseAdaptor(DatabaseAdaptor dbadaptor)
@ -522,34 +511,34 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
public String getInsertSessionStatementAsString()
{
return "insert into "+getTableName()+
" ("+getRowIdColumn()+", "+getIdColumn()+", "+getContextPathColumn()+", "+getVirtualHostColumn()+", "+getLastNodeColumn()+
" ("+getIdColumn()+", "+getContextPathColumn()+", "+getVirtualHostColumn()+", "+getLastNodeColumn()+
", "+getAccessTimeColumn()+", "+getLastAccessTimeColumn()+", "+getCreateTimeColumn()+", "+getCookieTimeColumn()+
", "+getLastSavedTimeColumn()+", "+getExpiryTimeColumn()+", "+getMaxIntervalColumn()+", "+getMapColumn()+") "+
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
}
public String getDeleteSessionStatementAsString()
public String getUpdateSessionStatementAsString(SessionKey key)
{
return "delete from "+getTableName()+
" where "+getRowIdColumn()+" = ?";
}
public String getUpdateSessionStatementAsString()
{
return "update "+getTableName()+
String s = "update "+getTableName()+
" set "+getIdColumn()+" = ?, "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+
getLastAccessTimeColumn()+" = ?, "+getLastSavedTimeColumn()+" = ?, "+getExpiryTimeColumn()+" = ?, "+
getMaxIntervalColumn()+" = ?, "+getMapColumn()+" = ? where "+getRowIdColumn()+" = ?";
}
public String getUpdateSessionNodeStatementAsString()
getMaxIntervalColumn()+" = ?, "+getMapColumn()+" = ? where ";
if (key.getCanonicalContextPath() == null || "".equals(key.getCanonicalContextPath()))
{
return "update "+getTableName()+
" set "+getLastNodeColumn()+" = ? where "+getRowIdColumn()+" = ?";
}
public String getUpdateSessionAccessTimeStatementAsString()
if (_dbAdaptor.isEmptyStringNull())
{
return "update "+getTableName()+
" set "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+getLastAccessTimeColumn()+" = ?, "+
getLastSavedTimeColumn()+" = ?, "+getExpiryTimeColumn()+" = ?, "+getMaxIntervalColumn()+" = ? where "+getRowIdColumn()+" = ?";
return s+getIdColumn()+" = ? and "+
getContextPathColumn()+" is null and "+
getVirtualHostColumn()+" = ?";
}
}
return s+getIdColumn()+" = ? and "+getContextPathColumn()+
" = ? and "+getVirtualHostColumn()+" = ?";
}
public String getBoundedExpiredSessionsStatementAsString()
{
@ -594,6 +583,42 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
}
public PreparedStatement getUpdateStatement (Connection connection, SessionKey key)
throws SQLException
{
if (_dbAdaptor == null)
throw new IllegalStateException("No DB adaptor");
String s = "update "+getTableName()+
" set "+getIdColumn()+" = ?, "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+
getLastAccessTimeColumn()+" = ?, "+getLastSavedTimeColumn()+" = ?, "+getExpiryTimeColumn()+" = ?, "+
getMaxIntervalColumn()+" = ?, "+getMapColumn()+" = ? where ";
if (key.getCanonicalContextPath() == null || "".equals(key.getCanonicalContextPath()))
{
if (_dbAdaptor.isEmptyStringNull())
{
PreparedStatement statement = connection.prepareStatement(s+getIdColumn()+" = ? and "+
getContextPathColumn()+" is null and "+
getVirtualHostColumn()+" = ?");
statement.setString(1, key.getId());
statement.setString(2, key.getVhost());
return statement;
}
}
PreparedStatement statement = connection.prepareStatement(s+getIdColumn()+" = ? and "+getContextPathColumn()+
" = ? and "+getVirtualHostColumn()+" = ?");
statement.setString(1, key.getId());
statement.setString(2, key.getCanonicalContextPath());
statement.setString(3, key.getVhost());
return statement;
}
public PreparedStatement getDeleteStatement (Connection connection, SessionKey key)
throws Exception
{
@ -717,91 +742,13 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
statement.executeUpdate(getCreateIndexOverExpiryStatementAsString(index1));
if (!index2Exists)
statement.executeUpdate(getCreateIndexOverSessionStatementAsString(index2));
//set up some strings representing the statements for session manipulation
_insertSession = getInsertSessionStatementAsString();
_deleteSession = getDeleteSessionStatementAsString();
_updateSession = getUpdateSessionStatementAsString();
_updateSessionNode = getUpdateSessionNodeStatementAsString();
_updateSessionAccessTime = getUpdateSessionAccessTimeStatementAsString();
_selectBoundedExpiredSessions = getBoundedExpiredSessionsStatementAsString();
_selectExpiredSessions = getSelectExpiredSessionsStatementAsString();
}
}
}
/**
* JDBCSessionData
*
*
*/
public class JDBCSessionData extends SessionData
{
protected String _rowId;
protected long _lastSaved; //time in msec since last save
/**
* @param id
* @param created
* @param accessed
* @param lastAccessed
* @param maxInactiveMs
*/
public JDBCSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
{
super(id, created, accessed, lastAccessed, maxInactiveMs);
}
public String getRowId()
{
return _rowId;
}
public void setRowId(String rowId)
{
_rowId = rowId;
}
public long getLastSaved()
{
return _lastSaved;
}
public void setLastSaved(long lastSaved)
{
_lastSaved = lastSaved;
}
public void setAttributes (Map<String, Object> attributes)
{
_attributes.putAll(attributes);
}
//TODO immutable??
public Map<String,Object> getAttributes ()
{
return _attributes;
}
}
/**
*
*/
public JDBCSessionDataStore ()
{
super ();
@ -826,7 +773,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
@Override
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
{
return new JDBCSessionData(id, created, accessed, lastAccessed, maxInactiveMs);
return new SessionData(id, created, accessed, lastAccessed, maxInactiveMs);
}
@ -881,15 +828,14 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, key);
ResultSet result = statement.executeQuery())
{
JDBCSessionData data = null;
SessionData data = null;
if (result.next())
{
data = (JDBCSessionData)newSessionData(key.getId(),
data = newSessionData(key.getId(),
result.getLong(_sessionTableSchema.getCreateTimeColumn()),
result.getLong(_sessionTableSchema.getAccessTimeColumn()),
result.getLong(_sessionTableSchema.getLastAccessTimeColumn()),
result.getLong(_sessionTableSchema.getMaxIntervalColumn()));
data.setRowId(result.getString(_sessionTableSchema.getRowIdColumn()));
data.setCookieSet(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
data.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn()));
data.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn()));
@ -901,7 +847,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
{
Object o = ois.readObject();
data.setAttributes((Map<String,Object>)o);
data.putAllAttributes((Map<String,Object>)o);
}
catch (Exception e)
{
@ -946,41 +892,109 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
@Override
public void doStore(SessionKey key, SessionData data) throws Exception
{
// TODO write session data to jdbc
if (data==null || key==null)
return;
try (Connection connection = _dbAdaptor.getConnection();
PreparedStatement statement = connection.prepareStatement(_sessionTableSchema.getUpdateSessionStatementAsString()))
try (Connection connection = _dbAdaptor.getConnection())
{
long now = System.currentTimeMillis();
connection.setAutoCommit(true);
statement.setString(1, key.getId());
statement.setString(2, data.getLastNode());//should be my node id
statement.setLong(3, data.getAccessed());//accessTime
statement.setLong(4, data.getLastAccessed()); //lastAccessTime
statement.setLong(5, now); //last saved time
statement.setLong(6, data.getExpiry());
statement.setLong(7, data.getMaxInactiveMs());
//If last saved field not set, then this is a fresh session that has never been persisted
if (data.getLastSaved() <= 0)
{
doInsert(connection, key, data);
}
else
{
doUpdate(connection, key, data);
}
}
}
private void doInsert (Connection connection, SessionKey key, SessionData data)
throws Exception
{
String s = _sessionTableSchema.getInsertSessionStatementAsString();
try (PreparedStatement statement = connection.prepareStatement(s))
{
long now = System.currentTimeMillis();
statement.setString(1, key.getId()); //session id
statement.setString(2, key.getCanonicalContextPath()); //context path
statement.setString(3, key.getVhost()); //first vhost
statement.setString(4, data.getLastNode());//my node id
statement.setLong(5, data.getAccessed());//accessTime
statement.setLong(6, data.getLastAccessed()); //lastAccessTime
statement.setLong(7, data.getCreated()); //time created
statement.setLong(8, data.getCookieSet());//time cookie was set
statement.setLong(9, now); //last saved time
statement.setLong(10, data.getExpiry());
statement.setLong(11, data.getMaxInactiveMs());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(((JDBCSessionData)data).getAttributes());
oos.writeObject(data.getAllAttributes());
oos.flush();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
statement.executeUpdate();
data.setLastSaved(now);
if (LOG.isDebugEnabled())
LOG.debug("Inserted session "+data);
}
}
private void doUpdate (Connection connection, SessionKey key, SessionData data)
throws Exception
{
try (PreparedStatement statement = connection.prepareStatement(_sessionTableSchema.getUpdateSessionStatementAsString(key)))
{
long now = System.currentTimeMillis();
statement.setString(1, data.getLastNode());//should be my node id
statement.setLong(2, data.getAccessed());//accessTime
statement.setLong(3, data.getLastAccessed()); //lastAccessTime
statement.setLong(4, now); //last saved time
statement.setLong(5, data.getExpiry());
statement.setLong(6, data.getMaxInactiveMs());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(data.getAllAttributes());
oos.flush();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
if ((key.getCanonicalContextPath() == null || "".equals(key.getCanonicalContextPath())) && _dbAdaptor.isEmptyStringNull())
{
statement.setString(8, key.getId());
statement.setString(9, key.getVhost());
}
else
{
statement.setString(8, key.getId());
statement.setString(9, key.getCanonicalContextPath());
statement.setString(10, key.getVhost());
}
statement.setBinaryStream(8, bais, bytes.length);//attribute map as blob
statement.setString(9, ((JDBCSessionData)data).getRowId()); //rowId
statement.executeUpdate();
((JDBCSessionData)data).setLastSaved(now);
}
data.setLastSaved(now);
if (LOG.isDebugEnabled())
LOG.debug("Updated session "+data);
}
}
/**
@ -989,7 +1003,24 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
@Override
public void scavenge()
{
// TODO Auto-generated method stub
if (LOG.isDebugEnabled())
LOG.debug("Scavenge sweep started at "+System.currentTimeMillis());
long now = System.currentTimeMillis();
//first time we're called, don't scavenge
if (_lastScavengeTime == 0)
{
_lastScavengeTime = now;
return;
}
/*TODO
* 1. Select sessions for our node and our context that have expired since our last pass, giving some leeway
* 2. Select sessions for our node that have expired some time ago
* 3. Select sessions for any node that have expired quite a while ago
*/
}

View File

@ -89,7 +89,7 @@ public class MemorySessionStore extends AbstractSessionStore
if (isStale(session))
{
//delete from memory
//delete from memory so should reload
doDelete(key);
return null;
}
@ -193,16 +193,4 @@ public class MemorySessionStore extends AbstractSessionStore
}
/**
* @see org.eclipse.jetty.server.session.x.SessionStore#scavenge()
*/
@Override
public void scavenge()
{
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,39 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session.x;
/**
* NeverStale
*
*
*/
public class NeverStaleStrategy implements StalenessStrategy
{
/**
* @see org.eclipse.jetty.server.session.x.StalenessStrategy#isStale(org.eclipse.jetty.server.session.x.Session)
*/
@Override
public boolean isStale(Session session)
{
return false;
}
}

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.server.session.x;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@ -33,6 +34,9 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public class SessionData implements Serializable
{
private static final long serialVersionUID = 1L;
protected String _id;
protected String _contextPath;
@ -50,7 +54,7 @@ public class SessionData implements Serializable
protected long _maxInactiveMs;
protected Map<String,Object> _attributes = new ConcurrentHashMap<String, Object>();
protected boolean _dirty;
protected long _lastSaved; //time in msec since last save
public SessionData (String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
@ -62,6 +66,20 @@ public class SessionData implements Serializable
_maxInactiveMs = maxInactiveMs;
}
public long getLastSaved()
{
return _lastSaved;
}
public void setLastSaved(long lastSaved)
{
_lastSaved = lastSaved;
}
public boolean isDirty()
{
return _dirty;
@ -93,6 +111,16 @@ public class SessionData implements Serializable
}
public void putAllAttributes (Map<String,Object> attributes)
{
_attributes.putAll(attributes);
}
public Map<String,Object> getAllAttributes()
{
return Collections.unmodifiableMap(_attributes);
}
public String getId()
{
return _id;

View File

@ -764,11 +764,14 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
Session session = _sessionStore.get(key);
if (session != null)
{
//TODO consider not allowing load of expired sessions inside stores
//if the session we loaded has expired
//If the session we got back has expired
if (session.isExpiredAt(System.currentTimeMillis()))
{
//Remove the expired session from cache and backing persistent store
//Tell the id manager that this session id should not be used in case other threads
//try to use the same session id in other contexts
_sessionIdManager.removeId(id);
//Remove the expired session from cache and any backing persistent store
try
{
_sessionStore.delete(key);
@ -778,10 +781,6 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
LOG.warn("Unable to delete expired session {}", key);
}
//Tell the id manager that this session id should not be used in case other threads
//try to use the same session id in other contexts
_sessionIdManager.removeId(id);
return null;
}
@ -799,9 +798,9 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
_sessionIdManager.removeId(id);
return null;
}
catch (Exception e1)
catch (Exception other)
{
LOG.warn(e1);
LOG.warn(other);
return null;
}
}
@ -996,24 +995,48 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
/* ------------------------------------------------------------ */
/**
* Tell the HttpSessionIdListeners the id changed.
* NOTE: this method must be called LAST in subclass overrides, after the session has been updated
* with the new id.
* @see org.eclipse.jetty.server.SessionManager#renewSessionId(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
* Change the session id and tell the HttpSessionIdListeners the id changed.
*
*/
@Override
public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
public void renewSessionId(String oldId, String oldExtendedId, String newId, String newExtendedId)
{
try
{
SessionKey oldKey = SessionKey.getKey(oldId, _context);
SessionKey newKey = SessionKey.getKey(newId, _context);
Session session = _sessionStore.get(oldKey);
if (session == null)
{
LOG.warn("Unable to renew id to "+newId+" for non-existant session "+oldId);
return;
}
//save session with new id
session.getSessionData().setId(newId);
session.setExtendedId(newExtendedId);
session.getSessionData().setLastSaved(0); //forces an insert
_sessionStore.put(newKey, session);
//remove session with old id
_sessionStore.delete(oldKey);
//inform the listeners
if (!_sessionIdListeners.isEmpty())
{
Session session = getSession(newClusterId);
HttpSessionEvent event = new HttpSessionEvent(session);
for (HttpSessionIdListener l:_sessionIdListeners)
{
l.sessionIdChanged(event, oldClusterId);
l.sessionIdChanged(event, oldId);
}
}
}
catch (Exception e)
{
LOG.warn(e);
}
}
public void scavenge ()

View File

@ -0,0 +1,70 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session.x;
/**
* StalePeriodStrategy
*
*
*/
public class StalePeriodStrategy implements StalenessStrategy
{
protected long _staleMs = 0;
/**
* @see org.eclipse.jetty.server.session.x.StalenessStrategy#isStale(org.eclipse.jetty.server.session.x.Session)
*/
@Override
public boolean isStale (Session session)
{
if (session == null)
return false;
//never persisted, must be fresh session
if (session.getSessionData().getLastSaved() == 0)
return false;
if (_staleMs <= 0)
{
//TODO always stale, never stale??
return false;
}
else
{
return (session.getSessionData().getAccessed() - session.getSessionData().getLastSaved() >= _staleMs);
}
}
public long getStaleSec ()
{
return (_staleMs<=0?0L:_staleMs/1000L);
}
public void setStaleSec (long sec)
{
if (sec == 0)
_staleMs = 0L;
else
_staleMs = sec * 1000L;
}
}

View File

@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session.x;
/**
* StalenessStrategy
*
*
*/
public interface StalenessStrategy
{
boolean isStale (Session session);
}