mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-05 22:39:52 -06:00
Retry duplicate exceptions to handle concurrent client sessions
Closes #42278 Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
committed by
GitHub
parent
4441ee4444
commit
e46c879cde
@@ -23,7 +23,6 @@ import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.util.Retry;
|
||||
import org.keycloak.models.AbstractKeycloakTransaction;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.sessions.infinispan.SessionFunction;
|
||||
@@ -150,10 +149,7 @@ abstract public class PersistentSessionsChangelogBasedTransaction<K, V extends S
|
||||
Retry.executeWithBackoff(
|
||||
iteration -> KeycloakModelUtils.runJobInTransaction(kcSession.getKeycloakSessionFactory(), super::applyChangesSynchronously),
|
||||
(iteration, t) -> {
|
||||
if (t instanceof ModelDuplicateException ex) {
|
||||
// duplicate exceptions are unlikely to succeed on a retry,
|
||||
throw ex;
|
||||
} else if (iteration > 20) {
|
||||
if (iteration > 20) {
|
||||
// never retry more than 20 times
|
||||
throw new RuntimeException("Maximum number of retries reached", t);
|
||||
}
|
||||
|
||||
@@ -31,11 +31,11 @@ import org.keycloak.testsuite.model.RequireProvider;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.aMapWithSize;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
@RequireProvider(UserSessionProvider.class)
|
||||
@@ -44,8 +44,6 @@ public class UserSessionConcurrencyTest extends KeycloakModelTest {
|
||||
private String realmId;
|
||||
private static final int CLIENTS_COUNT = 10;
|
||||
|
||||
private static final ThreadLocal<Boolean> wasWriting = ThreadLocal.withInitial(() -> false);
|
||||
|
||||
@Override
|
||||
public void createEnvironment(KeycloakSession s) {
|
||||
RealmModel realm = createRealm(s, "test");
|
||||
@@ -92,7 +90,6 @@ public class UserSessionConcurrencyTest extends KeycloakModelTest {
|
||||
UserSessionModel uSession = session.sessions().getUserSession(realm, uId);
|
||||
AuthenticatedClientSessionModel cSession = uSession.getAuthenticatedClientSessionByClient(client.getId());
|
||||
if (cSession == null) {
|
||||
wasWriting.set(true);
|
||||
cSession = session.sessions().createClientSession(realm, client, uSession);
|
||||
}
|
||||
|
||||
@@ -103,7 +100,8 @@ public class UserSessionConcurrencyTest extends KeycloakModelTest {
|
||||
cdl.countDown();
|
||||
}}));
|
||||
|
||||
cdl.await(10, TimeUnit.SECONDS);
|
||||
assertThat(cdl.await(10, TimeUnit.SECONDS), is(true));
|
||||
|
||||
withRealm(this.realmId, (session, realm) -> {
|
||||
UserSessionModel uSession = session.sessions().getUserSession(realm, uId);
|
||||
assertThat(uSession.getAuthenticatedClientSessions(), aMapWithSize(CLIENTS_COUNT));
|
||||
@@ -118,7 +116,7 @@ public class UserSessionConcurrencyTest extends KeycloakModelTest {
|
||||
return null;
|
||||
});
|
||||
|
||||
inComittedTransaction((Consumer<KeycloakSession>) session -> {
|
||||
inComittedTransaction(session -> {
|
||||
RealmModel realm = session.realms().getRealm(realmId);
|
||||
session.getContext().setRealm(realm);
|
||||
session.realms().removeRealm(realmId);
|
||||
|
||||
Reference in New Issue
Block a user