
org.zalando.riptide.failsafe.BackupRequestExecutor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of riptide-failsafe Show documentation
Show all versions of riptide-failsafe Show documentation
Client side response routing
The newest version!
package org.zalando.riptide.failsafe;
import dev.failsafe.spi.AsyncExecutionInternal;
import dev.failsafe.spi.ExecutionResult;
import dev.failsafe.spi.FailsafeFuture;
import dev.failsafe.spi.PolicyExecutor;
import dev.failsafe.spi.Scheduler;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Function;
import static org.zalando.riptide.CompletableFutures.forwardTo;
final class BackupRequestExecutor extends PolicyExecutor {
private final BackupRequest policy;
BackupRequestExecutor(final BackupRequest policy, int policyIndex) {
super(policy, policyIndex);
this.policy = policy;
}
@Override
public Function, CompletableFuture>> applyAsync(
Function, CompletableFuture>> innerFn,
final Scheduler scheduler,
final FailsafeFuture future) {
return (asyncExecutionInternal) -> {
final CompletableFuture> original = innerFn.apply(asyncExecutionInternal);
final CompletableFuture> backup = new CompletableFuture<>();
final Future> scheduledBackup = delay(scheduler, backup(innerFn, asyncExecutionInternal, backup));
original.whenComplete(cancel(scheduledBackup));
backup.whenComplete(cancel(original));
return anyOf(original, backup);
};
}
private Callable>> backup(
final Function, CompletableFuture>> innerFn,
final AsyncExecutionInternal asyncExecutionInternal,
final CompletableFuture> target) {
return () -> innerFn.apply(asyncExecutionInternal).whenComplete(forwardTo(target));
}
@SuppressWarnings("unchecked")
private ScheduledFuture delay(
final Scheduler scheduler,
final Callable callable) {
final long delay = policy.getDelay();
final TimeUnit unit = policy.getUnit();
return (ScheduledFuture) scheduler.schedule(callable, delay, unit);
}
private BiConsumer cancel(final Future> future) {
return (result, throwable) -> future.cancel(true);
}
@SafeVarargs
private final CompletableFuture anyOf(final CompletableFuture extends T>... futures) {
final CompletableFuture any = new CompletableFuture<>();
for (final CompletableFuture extends T> future : futures) {
future.whenComplete(forwardTo(any));
}
return any;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy