Make setting of last saved time less fragile.
This commit is contained in:
parent
b0748c5865
commit
b18769c1f9
|
@ -44,7 +44,7 @@ public abstract class AbstractSessionDataStore extends AbstractLifeCycle impleme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract void doStore(SessionKey key, SessionData data) throws Exception;
|
public abstract void doStore(SessionKey key, SessionData data, boolean isNew) throws Exception;
|
||||||
|
|
||||||
|
|
||||||
public Context getContext()
|
public Context getContext()
|
||||||
|
@ -65,9 +65,17 @@ public abstract class AbstractSessionDataStore extends AbstractLifeCycle impleme
|
||||||
@Override
|
@Override
|
||||||
public void store(SessionKey key, SessionData data) throws Exception
|
public void store(SessionKey key, SessionData data) throws Exception
|
||||||
{
|
{
|
||||||
|
long lastSave = data.getLastSaved();
|
||||||
|
|
||||||
|
data.setLastSaved(System.currentTimeMillis());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
doStore(key, data);
|
doStore(key, data, (lastSave<=0));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
//reset last save time
|
||||||
|
data.setLastSaved(lastSave);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -374,6 +374,8 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
||||||
|
|
||||||
removeId(oldClusterId);//remove the old one from the list (and database)
|
removeId(oldClusterId);//remove the old one from the list (and database)
|
||||||
|
|
||||||
|
useId(newClusterId); //add the new id to list
|
||||||
|
|
||||||
//tell all contexts to update the id
|
//tell all contexts to update the id
|
||||||
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
||||||
for (int i=0; contexts!=null && i<contexts.length; i++)
|
for (int i=0; contexts!=null && i<contexts.length; i++)
|
||||||
|
|
|
@ -231,28 +231,19 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
||||||
|
|
||||||
session.setSessionManager(_manager);
|
session.setSessionManager(_manager);
|
||||||
|
|
||||||
|
//if the session data has changed, or the cache is considered stale, write it to any backing store
|
||||||
|
if ((session.isNew() || session.getSessionData().isDirty() || isStale(session)) && _sessionDataStore != null)
|
||||||
|
{
|
||||||
|
session.willPassivate();
|
||||||
|
_sessionDataStore.store(key, session.getSessionData());
|
||||||
|
session.didActivate();
|
||||||
|
}
|
||||||
|
|
||||||
Session existing = doPutIfAbsent(key,session);
|
Session existing = doPutIfAbsent(key,session);
|
||||||
if (existing == null)
|
if (existing == null)
|
||||||
{
|
{
|
||||||
//session not already in cache write through
|
|
||||||
if (_sessionDataStore != null)
|
|
||||||
{
|
|
||||||
session.willPassivate();
|
|
||||||
_sessionDataStore.store(SessionKey.getKey(session.getSessionData()), session.getSessionData());
|
|
||||||
session.didActivate();
|
|
||||||
}
|
|
||||||
_sessionStats.increment();
|
_sessionStats.increment();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
//if the session data has changed, or the cache is considered stale, write it to any backing store
|
|
||||||
if ((session.getSessionData().isDirty() || isStale(session)) && _sessionDataStore != null)
|
|
||||||
{
|
|
||||||
session.willPassivate();
|
|
||||||
_sessionDataStore.store(key, session.getSessionData());
|
|
||||||
session.didActivate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -228,7 +228,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.SessionData)
|
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.SessionData)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doStore(SessionKey key, SessionData data) throws Exception
|
public void doStore(SessionKey key, SessionData data, boolean isNew) throws Exception
|
||||||
{
|
{
|
||||||
File file = null;
|
File file = null;
|
||||||
if (_storeDir != null)
|
if (_storeDir != null)
|
||||||
|
|
|
@ -308,7 +308,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+", "+getExpiryTimeColumn()+
|
PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getExpiryTimeColumn()+
|
||||||
" from "+getTableName()+" where "+getContextPathColumn()+" = ? and "+
|
" from "+getTableName()+" where "+getContextPathColumn()+" = ? and "+
|
||||||
getVirtualHostColumn()+" = ? and "+
|
getVirtualHostColumn()+" = ? and "+
|
||||||
getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?");
|
getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?");
|
||||||
|
@ -636,7 +636,6 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||||
_sessionTableSchema.setDatabaseAdaptor(_dbAdaptor);
|
_sessionTableSchema.setDatabaseAdaptor(_dbAdaptor);
|
||||||
_sessionTableSchema.prepareTables();
|
_sessionTableSchema.prepareTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -741,108 +740,101 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore()
|
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doStore(SessionKey key, SessionData data) throws Exception
|
public void doStore(SessionKey key, SessionData data, boolean isNew) throws Exception
|
||||||
{
|
{
|
||||||
if (data==null || key==null)
|
if (data==null || key==null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try (Connection connection = _dbAdaptor.getConnection())
|
if (isNew)
|
||||||
{
|
{
|
||||||
connection.setAutoCommit(true);
|
doInsert(key, data);
|
||||||
|
}
|
||||||
//If last saved field not set, then this is a fresh session that has never been persisted
|
else
|
||||||
if (data.getLastSaved() <= 0)
|
{
|
||||||
{
|
doUpdate(key, data);
|
||||||
doInsert(connection, key, data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
doUpdate(connection, key, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void doInsert (Connection connection, SessionKey key, SessionData data)
|
private void doInsert (SessionKey key, SessionData data)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
String s = _sessionTableSchema.getInsertSessionStatementAsString();
|
String s = _sessionTableSchema.getInsertSessionStatementAsString();
|
||||||
|
|
||||||
try (PreparedStatement statement = connection.prepareStatement(s))
|
|
||||||
|
try (Connection connection = _dbAdaptor.getConnection())
|
||||||
{
|
{
|
||||||
|
connection.setAutoCommit(true);
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(s))
|
||||||
|
{
|
||||||
|
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, data.getLastSaved()); //last saved time
|
||||||
|
statement.setLong(10, data.getExpiry());
|
||||||
|
statement.setLong(11, data.getMaxInactiveMs());
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
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.setString(1, key.getId()); //session id
|
statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
|
||||||
statement.setString(2, key.getCanonicalContextPath()); //context path
|
statement.executeUpdate();
|
||||||
statement.setString(3, key.getVhost()); //first vhost
|
if (LOG.isDebugEnabled())
|
||||||
statement.setString(4, data.getLastNode());//my node id
|
LOG.debug("Inserted session "+data);
|
||||||
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(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)
|
private void doUpdate (SessionKey key, SessionData data)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
try (PreparedStatement statement = _sessionTableSchema.getUpdateSessionStatement(connection, key.getCanonicalContextPath()))
|
try (Connection connection = _dbAdaptor.getConnection())
|
||||||
{
|
{
|
||||||
long now = System.currentTimeMillis();
|
connection.setAutoCommit(true);
|
||||||
|
try (PreparedStatement statement = _sessionTableSchema.getUpdateSessionStatement(connection, key.getCanonicalContextPath()))
|
||||||
|
{
|
||||||
|
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, data.getLastSaved()); //last saved time
|
||||||
|
statement.setLong(5, data.getExpiry());
|
||||||
|
statement.setLong(6, data.getMaxInactiveMs());
|
||||||
|
|
||||||
statement.setString(1, data.getLastNode());//should be my node id
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
statement.setLong(2, data.getAccessed());//accessTime
|
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||||
statement.setLong(3, data.getLastAccessed()); //lastAccessTime
|
oos.writeObject(data.getAllAttributes());
|
||||||
statement.setLong(4, now); //last saved time
|
oos.flush();
|
||||||
statement.setLong(5, data.getExpiry());
|
byte[] bytes = baos.toByteArray();
|
||||||
statement.setLong(6, data.getMaxInactiveMs());
|
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||||
|
statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
|
||||||
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
if ((key.getCanonicalContextPath() == null || "".equals(key.getCanonicalContextPath())) && _dbAdaptor.isEmptyStringNull())
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
{
|
||||||
oos.writeObject(data.getAllAttributes());
|
statement.setString(8, key.getId());
|
||||||
oos.flush();
|
statement.setString(9, key.getVhost());
|
||||||
byte[] bytes = baos.toByteArray();
|
}
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
else
|
||||||
statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
|
{
|
||||||
|
statement.setString(8, key.getId());
|
||||||
|
statement.setString(9, key.getCanonicalContextPath());
|
||||||
|
statement.setString(10, key.getVhost());
|
||||||
|
}
|
||||||
|
|
||||||
if ((key.getCanonicalContextPath() == null || "".equals(key.getCanonicalContextPath())) && _dbAdaptor.isEmptyStringNull())
|
statement.executeUpdate();
|
||||||
{
|
|
||||||
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.executeUpdate();
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Updated session "+data);
|
||||||
data.setLastSaved(now);
|
}
|
||||||
if (LOG.isDebugEnabled())
|
}
|
||||||
LOG.debug("Updated session "+data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore()
|
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doStore(SessionKey key, SessionData data) throws Exception
|
public void doStore(SessionKey key, SessionData data, boolean isNew) throws Exception
|
||||||
{
|
{
|
||||||
//noop
|
//noop
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ public abstract class AbstractForwardedSessionTest
|
||||||
|
|
||||||
HttpSession sess = request.getSession(false);
|
HttpSession sess = request.getSession(false);
|
||||||
assertNotNull(sess);
|
assertNotNull(sess);
|
||||||
|
assertNotNull(sess.getAttribute("servlet3"));
|
||||||
sess.setAttribute("servlet1", "servlet1");
|
sess.setAttribute("servlet1", "servlet1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,6 +145,7 @@ public abstract class AbstractForwardedSessionTest
|
||||||
//the session should exist after the forward
|
//the session should exist after the forward
|
||||||
HttpSession sess = request.getSession(false);
|
HttpSession sess = request.getSession(false);
|
||||||
assertNotNull(sess);
|
assertNotNull(sess);
|
||||||
|
assertNotNull(sess.getAttribute("servlet3"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue