From 5219a331b924aea04b6c17bca66ca6fcb54ccc5c Mon Sep 17 00:00:00 2001 From: Pedro Ruivo Date: Thu, 10 Jul 2025 19:40:28 +0100 Subject: [PATCH] Skip computing lifespan for read-only sessions Fixes #40980 Signed-off-by: Pedro Ruivo <1492066+pruivo@users.noreply.github.com> Co-authored-by: Pedro Ruivo <1492066+pruivo@users.noreply.github.com> --- .../InfinispanChangelogBasedTransaction.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/InfinispanChangelogBasedTransaction.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/InfinispanChangelogBasedTransaction.java index 3c3013b7714..cd6bcdc7ae4 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/InfinispanChangelogBasedTransaction.java +++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/InfinispanChangelogBasedTransaction.java @@ -18,6 +18,7 @@ package org.keycloak.models.sessions.infinispan.changes; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -153,13 +154,19 @@ public class InfinispanChangelogBasedTransaction ext for (Map.Entry> entry : updates.entrySet()) { SessionUpdatesList sessionUpdates = entry.getValue(); SessionEntityWrapper sessionWrapper = sessionUpdates.getEntityWrapper(); + List> updateTasks = sessionUpdates.getUpdateTasks(); + + if (updateTasks.isEmpty()) { + // no changes tracked, moving on. + continue; + } // Don't save transient entities to infinispan. They are valid just for current transaction if (sessionUpdates.getPersistenceState() == UserSessionModel.SessionPersistenceState.TRANSIENT) continue; // Don't save entities in infinispan that are both added and removed within the same transaction. - if (!sessionUpdates.getUpdateTasks().isEmpty() && sessionUpdates.getUpdateTasks().get(0).getOperation().equals(SessionUpdateTask.CacheOperation.ADD_IF_ABSENT) - && sessionUpdates.getUpdateTasks().get(sessionUpdates.getUpdateTasks().size() - 1).getOperation().equals(SessionUpdateTask.CacheOperation.REMOVE)) { + if (updateTasks.get(0).getOperation().equals(SessionUpdateTask.CacheOperation.ADD_IF_ABSENT) + && updateTasks.get(updateTasks.size() - 1).getOperation().equals(SessionUpdateTask.CacheOperation.REMOVE)) { continue; } @@ -168,7 +175,7 @@ public class InfinispanChangelogBasedTransaction ext long lifespanMs = lifespanMsLoader.apply(realm, sessionUpdates.getClient(), sessionWrapper.getEntity()); long maxIdleTimeMs = maxIdleTimeMsLoader.apply(realm, sessionUpdates.getClient(), sessionWrapper.getEntity()); - MergedUpdate merged = MergedUpdate.computeUpdate(sessionUpdates.getUpdateTasks(), sessionWrapper, lifespanMs, maxIdleTimeMs); + MergedUpdate merged = MergedUpdate.computeUpdate(updateTasks, sessionWrapper, lifespanMs, maxIdleTimeMs); if (merged != null) { // Now run the operation in our cluster