KEYCLOAK-5716 KEYCLOAK-5738 Avoid infinispan deadlock. Ensure code-to-token works correctly in cross-dc
This commit is contained in:
1 parent
1db3134df8
commit
62a1c187a2
28 files changed
+206
-108
No files matched your search
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.common.util;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class Retry {
|
||||
|
||||
/**
|
||||
* Runs the given {@code runnable} at most {@code retryCount} times until it passes,
|
||||
* leaving {@code intervalMillis} milliseconds between the invocations.
|
||||
* The runnable is reexecuted if it throws a {@link RuntimeException} or {@link AssertionError}.
|
||||
* @param runnable
|
||||
* @param attemptsCount Total number of attempts to execute the {@code runnable}
|
||||
* @param intervalMillis
|
||||
* @return Index of the first successful invocation, starting from 0.
|
||||
*/
|
||||
public static int execute(Runnable runnable, int attemptsCount, long intervalMillis) {
|
||||
int executionIndex = 0;
|
||||
while (true) {
|
||||
try {
|
||||
runnable.run();
|
||||
return executionIndex;
|
||||
} catch (RuntimeException | AssertionError e) {
|
||||
attemptsCount--;
|
||||
executionIndex++;
|
||||
if (attemptsCount > 0) {
|
||||
try {
|
||||
if (intervalMillis > 0) {
|
||||
Thread.sleep(intervalMillis);
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
ie.addSuppressed(e);
|
||||
throw new RuntimeException(ie);
|
||||
}
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given {@code runnable} at most {@code retryCount} times until it passes,
|
||||
* leaving {@code intervalMillis} milliseconds between the invocations.
|
||||
* The runnable is reexecuted if it throws a {@link RuntimeException} or {@link AssertionError}.
|
||||
* @param supplier
|
||||
* @param attemptsCount Total number of attempts to execute the {@code runnable}
|
||||
* @param intervalMillis
|
||||
* @return Value generated by the {@code supplier}.
|
||||
*/
|
||||
public static <T> T call(Supplier<T> supplier, int attemptsCount, long intervalMillis) {
|
||||
while (true) {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (RuntimeException | AssertionError e) {
|
||||
attemptsCount--;
|
||||
if (attemptsCount > 0) {
|
||||
try {
|
||||
if (intervalMillis > 0) {
|
||||
Thread.sleep(intervalMillis);
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
ie.addSuppressed(e);
|
||||
throw new RuntimeException(ie);
|
||||
}
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Needed here just because java.util.function.Supplier defined from Java 8
|
||||
*/
|
||||
public interface Supplier<T> {
|
||||
|
||||
/**
|
||||
* Gets a result.
|
||||
*
|
||||
* @return a result
|
||||
*/
|
||||
T get();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user