Avoid n+1 SQL selects to load sessions

Closes #32273

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
Alexander Schwartz 2024-08-20 16:03:41 +02:00 committed by Alexander Schwartz
parent 293333056f
commit a7964a588b
2 changed files with 21 additions and 19 deletions

View file

@ -223,7 +223,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
if (userSession.isOffline()) {
// If this is an offline session, and the referred online session doesn't exist anymore, don't register the client session in the transaction.
// Instead keep it transient and it will be added to the offline session only afterward. This is expected by SessionTimeoutsTest.testOfflineUserClientIdleTimeoutSmallerThanSessionOneRefresh.
if (sessionTx.get(realm, userSession.getId(), false) == null) {
if (sessionTx.get(realm, userSession.getId(), userSession, false) == null) {
return adapter;
}
}
@ -279,23 +279,23 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
@Override
public UserSessionModel getUserSession(RealmModel realm, String id) {
return getUserSession(realm, id, false);
return getUserSession(realm, id, null, false);
}
private UserSessionAdapter getUserSession(RealmModel realm, String id, boolean offline) {
SessionEntityWrapper<UserSessionEntity> entityWrapper = sessionTx.get(realm, id, offline);
private UserSessionAdapter getUserSession(RealmModel realm, String id, UserSessionModel userSession, boolean offline) {
SessionEntityWrapper<UserSessionEntity> entityWrapper = sessionTx.get(realm, id, userSession, offline);
return entityWrapper != null ? wrap(realm, entityWrapper.getEntity(), offline) : null;
}
private UserSessionEntity getUserSessionEntity(RealmModel realm, String id, boolean offline) {
SessionEntityWrapper<UserSessionEntity> entityWrapper = sessionTx.get(realm, id, offline);
SessionEntityWrapper<UserSessionEntity> entityWrapper = sessionTx.get(realm, id, null, offline);
return entityWrapper != null ? entityWrapper.getEntity() : null;
}
private Stream<UserSessionModel> getUserSessionsFromPersistenceProviderStream(RealmModel realm, UserModel user) {
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
return persister.loadUserSessionsStream(realm, user, true, 0, null)
.map(persistentUserSession -> (UserSessionModel) getUserSession(realm, persistentUserSession.getId(), true))
.map(persistentUserSession -> (UserSessionModel) getUserSession(realm, persistentUserSession.getId(), persistentUserSession, true))
.filter(Objects::nonNull);
}
@ -318,7 +318,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
if (user != null) {
return persister.loadUserSessionsStream(realm, user, offline, 0, null)
.filter(predicate.toModelPredicate())
.map(s -> (UserSessionModel) getUserSession(realm, s.getId(), offline))
.map(s -> (UserSessionModel) getUserSession(realm, s.getId(), s, offline))
.filter(Objects::nonNull);
} else {
return Stream.empty();
@ -337,7 +337,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
return userModel != null ?
persister.loadUserSessionsStream(realm, userModel, offline, 0, null)
.filter(predicate.toModelPredicate())
.map(s -> (UserSessionModel) getUserSession(realm, s.getId(), offline))
.map(s -> (UserSessionModel) getUserSession(realm, s.getId(), s, offline))
.filter(Objects::nonNull) :
Stream.empty();
}
@ -346,7 +346,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
ClientModel client = session.clients().getClientById(realm, predicate.getClient());
return persister.loadUserSessionsStream(realm, client, offline, 0, null)
.filter(predicate.toModelPredicate())
.map(s -> (UserSessionModel) getUserSession(realm, s.getId(), offline))
.map(s -> (UserSessionModel) getUserSession(realm, s.getId(), s, offline))
.filter(Objects::nonNull);
}
@ -354,7 +354,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
// we haven't yet migrated the old offline entries, so they don't have a brokerSessionId yet
return Stream.of(persister.loadUserSessionsStreamByBrokerSessionId(realm, predicate.getBrokerSessionId(), false))
.filter(predicate.toModelPredicate())
.map(s -> (UserSessionModel) getUserSession(realm, s.getId(), false))
.map(s -> (UserSessionModel) getUserSession(realm, s.getId(), s, false))
.filter(Objects::nonNull);
}
@ -412,7 +412,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
@Override
public UserSessionModel getUserSessionWithPredicate(RealmModel realm, String id, boolean offline, Predicate<UserSessionModel> predicate) {
UserSessionModel userSession = getUserSession(realm, id, offline);
UserSessionModel userSession = getUserSession(realm, id, null, offline);
if (userSession == null) {
return null;
}
@ -680,7 +680,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
@Override
public UserSessionAdapter getOfflineUserSession(RealmModel realm, String userSessionId) {
return getUserSession(realm, userSessionId, true);
return getUserSession(realm, userSessionId, null, true);
}
@Override

View file

@ -52,7 +52,7 @@ public class UserSessionPersistentChangelogBasedTransaction extends PersistentSe
super(session, USER_SESSION_CACHE_NAME, cache, offlineCache, remoteCacheInvoker, lifespanMsLoader, maxIdleTimeMsLoader, offlineLifespanMsLoader, offlineMaxIdleTimeMsLoader, batchingQueue, serializerOnline, serializerOffline);
}
public SessionEntityWrapper<UserSessionEntity> get(RealmModel realm, String key, boolean offline) {
public SessionEntityWrapper<UserSessionEntity> get(RealmModel realm, String key, UserSessionModel userSession, boolean offline) {
SessionUpdatesList<UserSessionEntity> myUpdates = getUpdates(offline).get(key);
if (myUpdates == null) {
SessionEntityWrapper<UserSessionEntity> wrappedEntity = null;
@ -63,7 +63,7 @@ public class UserSessionPersistentChangelogBasedTransaction extends PersistentSe
if (wrappedEntity == null) {
LOG.debugf("user-session not found in cache for sessionId=%s offline=%s, loading from persister", key, offline);
wrappedEntity = getSessionEntityFromPersister(realm, key, offline);
wrappedEntity = getSessionEntityFromPersister(realm, key, userSession, offline);
} else {
LOG.debugf("user-session found in cache for sessionId=%s offline=%s %s", key, offline, wrappedEntity.getEntity().getLastSessionRefresh());
}
@ -96,15 +96,17 @@ public class UserSessionPersistentChangelogBasedTransaction extends PersistentSe
}
}
private SessionEntityWrapper<UserSessionEntity> getSessionEntityFromPersister(RealmModel realm, String key, boolean offline) {
private SessionEntityWrapper<UserSessionEntity> getSessionEntityFromPersister(RealmModel realm, String key, UserSessionModel userSession, boolean offline) {
if (userSession == null) {
UserSessionPersisterProvider persister = kcSession.getProvider(UserSessionPersisterProvider.class);
UserSessionModel persistentUserSession = persister.loadUserSession(realm, key, offline);
userSession = persister.loadUserSession(realm, key, offline);
}
if (persistentUserSession == null) {
if (userSession == null) {
return null;
}
return importUserSession(persistentUserSession);
return importUserSession(userSession);
}
private SessionEntityWrapper<UserSessionEntity> importUserSession(UserSessionModel persistentUserSession) {