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()
|
||||
|
@ -65,9 +65,17 @@ public abstract class AbstractSessionDataStore extends AbstractLifeCycle impleme
|
|||
@Override
|
||||
public void store(SessionKey key, SessionData data) throws Exception
|
||||
{
|
||||
long lastSave = data.getLastSaved();
|
||||
|
||||
data.setLastSaved(System.currentTimeMillis());
|
||||
try
|
||||
{
|
||||
doStore(key, data);
|
||||
doStore(key, data, (lastSave<=0));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//reset last save time
|
||||
data.setLastSaved(lastSave);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -373,6 +373,8 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
|||
String newClusterId = newSessionId(request.hashCode());
|
||||
|
||||
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
|
||||
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
||||
|
|
|
@ -230,29 +230,20 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
throw new IllegalArgumentException ("Put key="+key+" session="+(session==null?"null":session.getId()));
|
||||
|
||||
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);
|
||||
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();
|
||||
}
|
||||
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)
|
||||
*/
|
||||
@Override
|
||||
public void doStore(SessionKey key, SessionData data) throws Exception
|
||||
public void doStore(SessionKey key, SessionData data, boolean isNew) throws Exception
|
||||
{
|
||||
File file = 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 "+
|
||||
getVirtualHostColumn()+" = ? and "+
|
||||
getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?");
|
||||
|
@ -636,7 +636,6 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
_sessionTableSchema.setDatabaseAdaptor(_dbAdaptor);
|
||||
_sessionTableSchema.prepareTables();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -741,108 +740,101 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore()
|
||||
*/
|
||||
@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)
|
||||
return;
|
||||
|
||||
try (Connection connection = _dbAdaptor.getConnection())
|
||||
{
|
||||
connection.setAutoCommit(true);
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
if (isNew)
|
||||
{
|
||||
doInsert(key, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
doUpdate(key, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void doInsert (Connection connection, SessionKey key, SessionData data)
|
||||
private void doInsert (SessionKey key, SessionData data)
|
||||
throws Exception
|
||||
{
|
||||
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();
|
||||
|
||||
|
||||
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(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);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
|
||||
statement.executeUpdate();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Inserted session "+data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doUpdate (Connection connection, SessionKey key, SessionData data)
|
||||
throws Exception
|
||||
private void doUpdate (SessionKey key, SessionData data)
|
||||
throws Exception
|
||||
{
|
||||
try (PreparedStatement statement = _sessionTableSchema.getUpdateSessionStatement(connection, key.getCanonicalContextPath()))
|
||||
{
|
||||
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
|
||||
try (Connection connection = _dbAdaptor.getConnection())
|
||||
{
|
||||
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());
|
||||
|
||||
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.executeUpdate();
|
||||
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
|
||||
|
||||
data.setLastSaved(now);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Updated session "+data);
|
||||
}
|
||||
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.executeUpdate();
|
||||
|
||||
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()
|
||||
*/
|
||||
@Override
|
||||
public void doStore(SessionKey key, SessionData data) throws Exception
|
||||
public void doStore(SessionKey key, SessionData data, boolean isNew) throws Exception
|
||||
{
|
||||
//noop
|
||||
}
|
||||
|
|
|
@ -126,6 +126,7 @@ public abstract class AbstractForwardedSessionTest
|
|||
|
||||
HttpSession sess = request.getSession(false);
|
||||
assertNotNull(sess);
|
||||
assertNotNull(sess.getAttribute("servlet3"));
|
||||
sess.setAttribute("servlet1", "servlet1");
|
||||
}
|
||||
}
|
||||
|
@ -144,6 +145,7 @@ public abstract class AbstractForwardedSessionTest
|
|||
//the session should exist after the forward
|
||||
HttpSession sess = request.getSession(false);
|
||||
assertNotNull(sess);
|
||||
assertNotNull(sess.getAttribute("servlet3"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue