Don't fetch expired user sessions from the database

Closes #32273

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
Alexander Schwartz 2024-08-20 16:42:51 +02:00 committed by Alexander Schwartz
parent 5740f8836a
commit 04d2126c73
2 changed files with 22 additions and 8 deletions

View file

@ -243,7 +243,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
@Override @Override
public void removeExpired(RealmModel realm) { public void removeExpired(RealmModel realm) {
int expiredOffline = Time.currentTime() - realm.getOfflineSessionIdleTimeout() - SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS; int expiredOffline = calculateOldestSessionTime(realm, true) - SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS;
// prefer client session timeout if set // prefer client session timeout if set
int expiredClientOffline = expiredOffline; int expiredClientOffline = expiredOffline;
@ -255,7 +255,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
if (MultiSiteUtils.isPersistentSessionsEnabled()) { if (MultiSiteUtils.isPersistentSessionsEnabled()) {
int expired = Time.currentTime() - Math.max(realm.getSsoSessionIdleTimeout(), realm.getSsoSessionIdleTimeoutRememberMe()) - SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS; int expired = calculateOldestSessionTime(realm, false) - SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS;
// prefer client session timeout if set // prefer client session timeout if set
int expiredClient = expired; int expiredClient = expired;
@ -267,6 +267,14 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
} }
} }
private int calculateOldestSessionTime(RealmModel realm, boolean offline) {
if (offline) {
return Time.currentTime() - realm.getOfflineSessionIdleTimeout();
} else {
return Time.currentTime() - Math.max(realm.getSsoSessionIdleTimeout(), realm.getSsoSessionIdleTimeoutRememberMe());
}
}
private void expire(RealmModel realm, int expiredClientOffline, int expiredOffline, boolean offline) { private void expire(RealmModel realm, int expiredClientOffline, int expiredOffline, boolean offline) {
String offlineStr = offlineToString(offline); String offlineStr = offlineToString(offline);
@ -296,6 +304,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
query.setParameter("offline", offlineStr); query.setParameter("offline", offlineStr);
query.setParameter("realmId", realm.getId()); query.setParameter("realmId", realm.getId());
query.setParameter("lastSessionRefresh", calculateOldestSessionTime(realm, offline));
return closing(query.getResultStream()) return closing(query.getResultStream())
.collect(Collectors.toMap(row -> { .collect(Collectors.toMap(row -> {
@ -318,6 +327,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
userSessionQuery.setParameter("realmId", realm.getId()); userSessionQuery.setParameter("realmId", realm.getId());
userSessionQuery.setParameter("offline", offlineStr); userSessionQuery.setParameter("offline", offlineStr);
userSessionQuery.setParameter("userSessionId", userSessionId); userSessionQuery.setParameter("userSessionId", userSessionId);
userSessionQuery.setParameter("lastSessionRefresh", calculateOldestSessionTime(realm, offline));
userSessionQuery.setMaxResults(1); userSessionQuery.setMaxResults(1);
Stream<OfflineUserSessionModel> persistentUserSessions = closing(userSessionQuery.getResultStream().map(this::toAdapter)); Stream<OfflineUserSessionModel> persistentUserSessions = closing(userSessionQuery.getResultStream().map(this::toAdapter));
@ -352,6 +362,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
userSessionQuery.setParameter("realmId", realm.getId()); userSessionQuery.setParameter("realmId", realm.getId());
userSessionQuery.setParameter("brokerSessionId", brokerSessionId); userSessionQuery.setParameter("brokerSessionId", brokerSessionId);
userSessionQuery.setParameter("offline", offlineToString(offline)); userSessionQuery.setParameter("offline", offlineToString(offline));
userSessionQuery.setParameter("lastSessionRefresh", calculateOldestSessionTime(realm, offline));
userSessionQuery.setMaxResults(1); userSessionQuery.setMaxResults(1);
Stream<OfflineUserSessionModel> persistentUserSessions = closing(userSessionQuery.getResultStream().map(this::toAdapter)); Stream<OfflineUserSessionModel> persistentUserSessions = closing(userSessionQuery.getResultStream().map(this::toAdapter));
@ -391,12 +402,14 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
em.createNamedQuery("findUserSessionsByClientId", PersistentUserSessionEntity.class), em.createNamedQuery("findUserSessionsByClientId", PersistentUserSessionEntity.class),
firstResult, maxResults); firstResult, maxResults);
query.setParameter("clientId", client.getId()); query.setParameter("clientId", client.getId());
query.setParameter("lastSessionRefresh", calculateOldestSessionTime(realm, offline));
} else { } else {
query = paginateQuery( query = paginateQuery(
em.createNamedQuery("findUserSessionsByExternalClientId", PersistentUserSessionEntity.class), em.createNamedQuery("findUserSessionsByExternalClientId", PersistentUserSessionEntity.class),
firstResult, maxResults); firstResult, maxResults);
query.setParameter("clientStorageProvider", clientStorageId.getProviderId()); query.setParameter("clientStorageProvider", clientStorageId.getProviderId());
query.setParameter("externalClientId", clientStorageId.getExternalId()); query.setParameter("externalClientId", clientStorageId.getExternalId());
query.setParameter("lastSessionRefresh", calculateOldestSessionTime(realm, offline));
} }
query.setParameter("offline", offlineStr); query.setParameter("offline", offlineStr);
@ -417,6 +430,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
query.setParameter("offline", offlineStr); query.setParameter("offline", offlineStr);
query.setParameter("realmId", realm.getId()); query.setParameter("realmId", realm.getId());
query.setParameter("userId", user.getId()); query.setParameter("userId", user.getId());
query.setParameter("lastSessionRefresh", calculateOldestSessionTime(realm, offline));
return loadUserSessionsWithClientSessions(query, offlineStr, true); return loadUserSessionsWithClientSessions(query, offlineStr, true);
} }

View file

@ -44,20 +44,20 @@ import java.io.Serializable;
" AND sess.userSessionId > :lastSessionId" + " AND sess.userSessionId > :lastSessionId" +
" order by sess.userSessionId"), " order by sess.userSessionId"),
@NamedQuery(name="findUserSession", query="select sess from PersistentUserSessionEntity sess where sess.offline = :offline" + @NamedQuery(name="findUserSession", query="select sess from PersistentUserSessionEntity sess where sess.offline = :offline" +
" AND sess.userSessionId = :userSessionId AND sess.realmId = :realmId"), " AND sess.userSessionId = :userSessionId AND sess.realmId = :realmId AND sess.lastSessionRefresh >= :lastSessionRefresh"),
@NamedQuery(name="findUserSessionsByUserId", query="select sess from PersistentUserSessionEntity sess where sess.offline = :offline" + @NamedQuery(name="findUserSessionsByUserId", query="select sess from PersistentUserSessionEntity sess where sess.offline = :offline" +
" AND sess.realmId = :realmId AND sess.userId = :userId ORDER BY sess.userSessionId"), " AND sess.realmId = :realmId AND sess.userId = :userId AND sess.lastSessionRefresh >= :lastSessionRefresh ORDER BY sess.userSessionId"),
@NamedQuery(name="findUserSessionsByBrokerSessionId", query="select sess from PersistentUserSessionEntity sess where sess.brokerSessionId = :brokerSessionId" + @NamedQuery(name="findUserSessionsByBrokerSessionId", query="select sess from PersistentUserSessionEntity sess where sess.brokerSessionId = :brokerSessionId" +
" AND sess.realmId = :realmId AND sess.offline = :offline ORDER BY sess.userSessionId"), " AND sess.realmId = :realmId AND sess.offline = :offline AND lastSessionRefresh >= :lastSessionRefresh ORDER BY sess.userSessionId"),
@NamedQuery(name="findUserSessionsByClientId", query="SELECT sess FROM PersistentUserSessionEntity sess INNER JOIN PersistentClientSessionEntity clientSess " + @NamedQuery(name="findUserSessionsByClientId", query="SELECT sess FROM PersistentUserSessionEntity sess INNER JOIN PersistentClientSessionEntity clientSess " +
" ON sess.userSessionId = clientSess.userSessionId AND sess.offline = clientSess.offline AND clientSess.clientId = :clientId WHERE sess.offline = :offline " + " ON sess.userSessionId = clientSess.userSessionId AND sess.offline = clientSess.offline AND clientSess.clientId = :clientId WHERE sess.offline = :offline " +
" AND sess.realmId = :realmId ORDER BY sess.userSessionId"), " AND sess.realmId = :realmId AND sess.lastSessionRefresh >= :lastSessionRefresh ORDER BY sess.userSessionId"),
@NamedQuery(name="findUserSessionsByExternalClientId", query="SELECT sess FROM PersistentUserSessionEntity sess INNER JOIN PersistentClientSessionEntity clientSess " + @NamedQuery(name="findUserSessionsByExternalClientId", query="SELECT sess FROM PersistentUserSessionEntity sess INNER JOIN PersistentClientSessionEntity clientSess " +
" ON sess.userSessionId = clientSess.userSessionId AND clientSess.clientStorageProvider = :clientStorageProvider AND sess.offline = clientSess.offline AND clientSess.externalClientId = :externalClientId WHERE sess.offline = :offline " + " ON sess.userSessionId = clientSess.userSessionId AND clientSess.clientStorageProvider = :clientStorageProvider AND sess.offline = clientSess.offline AND clientSess.externalClientId = :externalClientId WHERE sess.offline = :offline " +
" AND sess.realmId = :realmId ORDER BY sess.userSessionId"), " AND sess.realmId = :realmId AND sess.lastSessionRefresh >= :lastSessionRefresh ORDER BY sess.userSessionId"),
@NamedQuery(name="findClientSessionsClientIds", query="SELECT clientSess.clientId, clientSess.externalClientId, clientSess.clientStorageProvider, count(clientSess)" + @NamedQuery(name="findClientSessionsClientIds", query="SELECT clientSess.clientId, clientSess.externalClientId, clientSess.clientStorageProvider, count(clientSess)" +
" FROM PersistentClientSessionEntity clientSess INNER JOIN PersistentUserSessionEntity sess ON clientSess.userSessionId = sess.userSessionId AND sess.offline = clientSess.offline" + " FROM PersistentClientSessionEntity clientSess INNER JOIN PersistentUserSessionEntity sess ON clientSess.userSessionId = sess.userSessionId AND sess.offline = clientSess.offline" +
" WHERE sess.offline = :offline AND sess.realmId = :realmId " + " WHERE sess.offline = :offline AND sess.realmId = :realmId AND sess.lastSessionRefresh >= :lastSessionRefresh" +
" GROUP BY clientSess.clientId, clientSess.externalClientId, clientSess.clientStorageProvider") " GROUP BY clientSess.clientId, clientSess.externalClientId, clientSess.clientStorageProvider")
}) })