Don't save sessions on server shutdown if database already closed

Affects issues:
- #3436
This commit is contained in:
Aurora Lahtela 2024-02-17 09:19:38 +02:00
parent bede36957b
commit b867bcebdb
2 changed files with 14 additions and 18 deletions

View File

@ -48,7 +48,6 @@ public abstract class ServerShutdownSave {
private final ErrorLogger errorLogger;
private boolean shuttingDown = false;
private boolean startedDatabase = false;
protected ServerShutdownSave(
Locale locale,
@ -90,7 +89,7 @@ public abstract class ServerShutdownSave {
private Optional<Future<?>> attemptSave(Collection<ActiveSession> activeSessions) {
try {
return Optional.of(saveActiveSessions(finishSessions(activeSessions, System.currentTimeMillis())));
return saveActiveSessions(finishSessions(activeSessions, System.currentTimeMillis()));
} catch (DBInitException e) {
errorLogger.error(e, ErrorContext.builder()
.whatToDo("Find the sessions in the error file and save them manually or ignore. Report & delete the error file after.")
@ -101,20 +100,19 @@ public abstract class ServerShutdownSave {
} catch (IllegalStateException ignored) {
/* Database is not initialized */
return Optional.empty();
} finally {
closeDatabase(dbSystem.getDatabase());
}
}
private Future<?> saveActiveSessions(Collection<FinishedSession> finishedSessions) {
private Optional<Future<?>> saveActiveSessions(Collection<FinishedSession> finishedSessions) {
Database database = dbSystem.getDatabase();
if (database.getState() == Database.State.CLOSED) {
// Ensure that database is not closed when performing the transaction.
startedDatabase = true;
database.init();
// Don't attempt to save if database is closed, session storage will be handled by
// ShutdownDataPreservation instead.
// Previously database reboot was attempted, but this could lead to server hang.
return Optional.empty();
}
return saveSessions(finishedSessions, database);
return Optional.of(saveSessions(finishedSessions, database));
}
Collection<FinishedSession> finishSessions(Collection<ActiveSession> activeSessions, long now) {
@ -127,10 +125,4 @@ public abstract class ServerShutdownSave {
private Future<?> saveSessions(Collection<FinishedSession> finishedSessions, Database database) {
return database.executeTransaction(new ServerShutdownTransaction(finishedSessions));
}
private void closeDatabase(Database database) {
if (startedDatabase) {
database.close();
}
}
}

View File

@ -122,9 +122,15 @@ class ShutdownSaveTest {
Optional<Future<?>> future = underTest.performSave();
assertTrue(future.isEmpty());
database.init();
assertTrue(database.query(SessionQueries.fetchAllSessions()).isEmpty());
}
@Test
void sessionsAreNotSavedIfDatabaseIsClosed() {
shutdownStatus = true;
database.close();
Optional<Future<?>> future = underTest.performSave();
assertTrue(future.isEmpty());
}
@Test
@ -134,9 +140,7 @@ class ShutdownSaveTest {
assertTrue(save.isPresent());
save.get().get(); // Wait for save to be done, test fails without.
database.init();
assertFalse(database.query(SessionQueries.fetchAllSessions()).isEmpty());
database.close();
}
private void placeSessionToCache() {