
io.etcd.jetcd.impl.Impl Maven / Gradle / Ivy
package io.etcd.jetcd.impl;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.etcd.jetcd.common.exception.EtcdExceptionFactory;
import io.etcd.jetcd.support.Errors;
import io.grpc.Status;
import io.vertx.core.Future;
import net.jodah.failsafe.Failsafe;
import net.jodah.failsafe.RetryPolicy;
import static io.etcd.jetcd.support.Errors.isInvalidTokenError;
abstract class Impl {
private final Logger logger;
private final ClientConnectionManager connectionManager;
protected Impl(ClientConnectionManager connectionManager) {
this.connectionManager = connectionManager;
this.logger = LoggerFactory.getLogger(getClass());
}
protected ClientConnectionManager connectionManager() {
return this.connectionManager;
}
protected Logger logger() {
return this.logger;
}
/**
* Converts Future of Type S to CompletableFuture of Type T.
*
* @param sourceFuture the Future to wrap
* @param resultConvert the result converter
* @return a {@link CompletableFuture} wrapping the given {@link Future}
*/
protected CompletableFuture completable(Future sourceFuture, Function resultConvert) {
return completable(sourceFuture, resultConvert, EtcdExceptionFactory::toEtcdException);
}
/**
* Converts Future of Type S to CompletableFuture of Type T.
*
* @param sourceFuture the Future to wrap
* @param resultConvert the result converter
* @param exceptionConverter the exception mapper
* @return a {@link CompletableFuture} wrapping the given {@link Future}
*/
protected CompletableFuture completable(
Future sourceFuture,
Function resultConvert,
Function exceptionConverter) {
return completable(
sourceFuture.compose(
r -> Future.succeededFuture(resultConvert.apply(r)),
e -> Future.failedFuture(exceptionConverter.apply(e))));
}
/**
* Converts Future of Type S to CompletableFuture of Type T.
*
* @param sourceFuture the Future to wrap
* @return a {@link CompletableFuture} wrapping the given {@link Future}
*/
protected CompletableFuture completable(
Future sourceFuture) {
return sourceFuture.toCompletionStage().toCompletableFuture();
}
/**
* execute the task and retry it in case of failure.
*
* @param supplier a function that returns a new Future.
* @param resultConvert a function that converts Type S to Type T.
* @param Source type
* @param Converted Type.
* @return a CompletableFuture with type T.
*/
protected CompletableFuture execute(
Supplier> supplier,
Function resultConvert) {
return execute(supplier, resultConvert, Errors::isRetryable);
}
/**
* execute the task and retry it in case of failure.
*
* @param supplier a function that returns a new Future.
* @param resultConvert a function that converts Type S to Type T.
* @param doRetry a predicate to determine if a failure has to be retried
* @param Source type
* @param Converted Type.
* @return a CompletableFuture with type T.
*/
protected CompletableFuture execute(
Supplier> supplier,
Function resultConvert,
Predicate doRetry) {
RetryPolicy retryPolicy = new RetryPolicy()
.handleIf(throwable -> {
Status status = Status.fromThrowable(throwable);
if (isInvalidTokenError(status)) {
connectionManager.authCredential().refresh();
}
return doRetry.test(status);
})
.onRetriesExceeded(e -> logger.warn("maximum number of auto retries reached"))
.withBackoff(
connectionManager.builder().retryDelay(),
connectionManager.builder().retryMaxDelay(),
connectionManager.builder().retryChronoUnit());
if (connectionManager.builder().retryMaxDuration() != null) {
retryPolicy = retryPolicy.withMaxDuration(connectionManager.builder().retryMaxDuration());
}
return Failsafe
.with(retryPolicy)
.with(connectionManager.getExecutorService())
.getStageAsync(() -> supplier.get().toCompletionStage())
.thenApply(resultConvert);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy