Skip to content

Commit

Permalink
Remove FailsafeExecutor overloads for withFallback
Browse files Browse the repository at this point in the history
  • Loading branch information
jhalterman committed Jan 14, 2019
1 parent 1be79b3 commit 2186b3d
Show file tree
Hide file tree
Showing 9 changed files with 26 additions and 104 deletions.
1 change: 1 addition & 0 deletions src/main/java/net/jodah/failsafe/AsyncExecution.java
Expand Up @@ -38,6 +38,7 @@ public final class AsyncExecution extends AbstractExecution {
private volatile boolean completeCalled;
private volatile boolean retryCalled;

@SuppressWarnings("unchecked")
<T> AsyncExecution(Scheduler scheduler, FailsafeFuture<T> future, FailsafeExecutor<?> executor) {
super((FailsafeExecutor<Object>) executor);
this.scheduler = scheduler;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/jodah/failsafe/ExecutionContext.java
Expand Up @@ -23,7 +23,7 @@
* @author Jonathan Halterman
*/
public class ExecutionContext {
final Duration startTime;
private final Duration startTime;
/** Number of execution attempts */
volatile int executions;

Expand Down
82 changes: 2 additions & 80 deletions src/main/java/net/jodah/failsafe/FailsafeExecutor.java
Expand Up @@ -321,93 +321,15 @@ public FailsafeExecutor<R> with(RetryPolicy<R> retryPolicy) {
return this;
}

/**
* Configures the {@code fallback} action to be executed if execution fails.
*
* @throws NullPointerException if {@code fallback} is null
* @throws IllegalStateException if {@code withFallback} method has already been called or if ordered policies
* have been configured
*/
public FailsafeExecutor<R> withFallback(CheckedSupplier<? extends R> fallback) {
return withFallback(Fallback.of(fallback));
}

/**
* Configures the {@code fallback} action to be executed if execution fails.
*
* @throws NullPointerException if {@code fallback} is null
* @throws IllegalStateException if {@code withFallback} method has already been called or if ordered policies
* have been configured
*/
public FailsafeExecutor<R> withFallback(CheckedBiConsumer<? extends R, ? extends Throwable> fallback) {
return withFallback(Fallback.of(fallback));
}

/**
* Configures the {@code fallback} action to be executed if execution fails.
*
* @throws NullPointerException if {@code fallback} is null
* @throws IllegalStateException if {@code withFallback} method has already been called or if ordered policies
* have been configured
*/
public FailsafeExecutor<R> withFallback(CheckedBiFunction<? extends R, ? extends Throwable, ? extends R> fallback) {
withFallback(Fallback.of(fallback));
return this;
}

/**
* Configures the {@code fallback} action to be executed if execution fails.
*
* @throws NullPointerException if {@code fallback} is null
* @throws IllegalStateException if {@code withFallback} method has already been called or if ordered policies
* have been configured
*/
public FailsafeExecutor<R> withFallback(CheckedConsumer<? extends Throwable> fallback) {
return withFallback(Fallback.of(fallback));
}

/**
* Configures the {@code fallback} action to be executed if execution fails.
*
* @throws NullPointerException if {@code fallback} is null
* @throws IllegalStateException if {@code withFallback} method has already been called or if ordered policies
* have been configured
*/
public FailsafeExecutor<R> withFallback(CheckedFunction<? extends Throwable, ? extends R> fallback) {
return withFallback(Fallback.of(fallback));
}

/**
* Configures the {@code fallback} action to be executed if execution fails.
*
* @throws NullPointerException if {@code fallback} is null
* @throws IllegalStateException if {@code withFallback} method has already been called or if ordered policies
* have been configured
*/
public FailsafeExecutor<R> withFallback(CheckedRunnable fallback) {
return withFallback(Fallback.of(fallback));
}

/**
* Configures the {@code fallback} result to be returned if execution fails.
*
* @throws NullPointerException if {@code fallback} is null
* @throws IllegalStateException if {@code withFallback} method has already been called or if ordered policies
* have been configured
*/
public FailsafeExecutor<R> withFallback(R fallback) {
return withFallback(Fallback.of(fallback));
}

/**
* Configures the {@code fallback} result to be returned if execution fails.
*
* @throws NullPointerException if {@code fallback} is null
* @throws IllegalStateException if {@code withFallback} method has already been called or if ordered policies
* have been configured
*/
public FailsafeExecutor<R> withFallback(Fallback<R> fallback) {
Assert.state(this.fallback == null, "withFallback has already been called");
public FailsafeExecutor<R> with(Fallback<R> fallback) {
Assert.state(this.fallback == null, "A fallback has already been configured");
Assert.state(policies == null || policies.isEmpty(), "Policies have already been configured");
this.fallback = Assert.notNull(fallback, "fallback");
return this;
Expand Down
8 changes: 4 additions & 4 deletions src/test/java/net/jodah/failsafe/AbstractFailsafeTest.java
Expand Up @@ -94,17 +94,17 @@ void failsafeRun(CircuitBreaker<?> breaker, CheckedRunnable runnable) {
*/
<T> T failsafeGet(CircuitBreaker<T> breaker, CheckedBiFunction<T, Throwable, T> fallback, CheckedSupplier<T> supplier) {
ScheduledExecutorService executor = getExecutor();
return unwrapExceptions(() -> executor == null ? Failsafe.with(breaker).withFallback(fallback).get(supplier)
: Failsafe.with(breaker).with(executor).withFallback(fallback).getAsync(supplier).get());
return unwrapExceptions(() -> executor == null ? Failsafe.with(breaker).with(Fallback.of(fallback)).get(supplier)
: Failsafe.with(breaker).with(executor).with(Fallback.of(fallback)).getAsync(supplier).get());
}

/**
* Does a failsafe get with an optional executor.
*/
<T> T failsafeGet(RetryPolicy<T> retryPolicy, CheckedBiFunction<T, Throwable, T> fallback, CheckedSupplier<T> supplier) {
ScheduledExecutorService executor = getExecutor();
return unwrapExceptions(() -> executor == null ? Failsafe.with(retryPolicy).withFallback(fallback).get(supplier)
: Failsafe.with(retryPolicy).with(executor).withFallback(fallback).getAsync(supplier).get());
return unwrapExceptions(() -> executor == null ? Failsafe.with(retryPolicy).with(Fallback.of(fallback)).get(supplier)
: Failsafe.with(retryPolicy).with(executor).with(Fallback.of(fallback)).getAsync(supplier).get());
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/net/jodah/failsafe/AsyncFailsafeTest.java
Expand Up @@ -398,7 +398,7 @@ public void shouldHandleInitialSchedulingFailure() {
// When
Future future = Failsafe.with(new CircuitBreaker<>())
.with(new RetryPolicy<>())
.withFallback(false)
.with(Fallback.of(false))
.with(executor)
.runAsync(() -> waiter.fail("Should not execute supplier since executor has been shutdown"));

Expand Down
Expand Up @@ -17,6 +17,7 @@

import net.jodah.failsafe.ExecutionContext;
import net.jodah.failsafe.Failsafe;
import net.jodah.failsafe.Fallback;
import net.jodah.failsafe.RetryPolicy;
import org.testng.annotations.Test;

Expand Down Expand Up @@ -67,7 +68,7 @@ public void shouldDelayOnMatchingResult() {
}, "expected");

AtomicInteger attempts = new AtomicInteger(0);
Object result = Failsafe.with(retryPolicy).withFallback(123).get(() -> {
Object result = Failsafe.with(retryPolicy).with(Fallback.of(123)).get(() -> {
int i = attempts.getAndIncrement();
switch (i) {
case 0:
Expand All @@ -94,7 +95,7 @@ public void shouldDelayOnMatchingFailureType() {
}, DelayException.class);

AtomicInteger attempts = new AtomicInteger(0);
int result = Failsafe.with(retryPolicy).withFallback(123).get(() -> {
int result = Failsafe.with(retryPolicy).with(Fallback.of(123)).get(() -> {
int i = attempts.getAndIncrement();
switch (i) {
case 0:
Expand Down
16 changes: 8 additions & 8 deletions src/test/java/net/jodah/failsafe/issues/Issue55Test.java
Expand Up @@ -15,31 +15,31 @@
*/
package net.jodah.failsafe.issues;

import static org.testng.Assert.assertEquals;
import net.jodah.failsafe.Failsafe;
import net.jodah.failsafe.Fallback;
import net.jodah.failsafe.RetryPolicy;
import org.testng.annotations.Test;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicInteger;

import org.testng.annotations.Test;

import net.jodah.failsafe.Failsafe;
import net.jodah.failsafe.RetryPolicy;
import static org.testng.Assert.assertEquals;

@Test
public class Issue55Test {
public void shouldOnlyFallbackOnFailure() throws Throwable {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

AtomicInteger counter = new AtomicInteger();
Failsafe.with(new RetryPolicy()).with(executor).withFallback(() -> counter.incrementAndGet()).getAsync(() -> null);
Failsafe.with(new RetryPolicy<>()).with(executor).with(Fallback.of(counter::incrementAndGet)).getAsync(() -> null);

Thread.sleep(100);
assertEquals(counter.get(), 0);

Failsafe.with(new RetryPolicy().withMaxRetries(1))
Failsafe.with(new RetryPolicy<>().withMaxRetries(1))
.with(executor)
.withFallback(() -> counter.incrementAndGet())
.with(Fallback.of(counter::incrementAndGet))
.runAsync(() -> {
throw new RuntimeException();
});
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/net/jodah/failsafe/issues/Issue75Test.java
Expand Up @@ -2,6 +2,7 @@

import net.jodah.failsafe.CircuitBreaker;
import net.jodah.failsafe.Failsafe;
import net.jodah.failsafe.Fallback;
import org.testng.Assert;
import org.testng.annotations.Test;

Expand All @@ -18,7 +19,7 @@ public void testThatFailSafeIsBrokenWithFallback() throws Exception {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
int result = Failsafe.with(breaker)
.with(service)
.withFallback((a, b) -> 999)
.with(Fallback.of((a, b) -> 999))
.futureAsync(() -> CompletableFuture.completedFuture(223))
.get();

Expand Down
11 changes: 4 additions & 7 deletions src/test/java/net/jodah/failsafe/issues/Issue84Test.java
@@ -1,9 +1,6 @@
package net.jodah.failsafe.issues;

import net.jodah.failsafe.Asserts;
import net.jodah.failsafe.CircuitBreaker;
import net.jodah.failsafe.CircuitBreakerOpenException;
import net.jodah.failsafe.Failsafe;
import net.jodah.failsafe.*;
import org.testng.annotations.Test;

import java.util.concurrent.*;
Expand All @@ -21,14 +18,14 @@ public void shouldHandleCircuitBreakerOpenException() throws Throwable {
Asserts.assertThrows(() -> Failsafe.with(circuitBreaker).get(() -> true), CircuitBreakerOpenException.class);

// Synchronous with fallback
assertFalse(Failsafe.with(circuitBreaker).withFallback(false).get(() -> true));
assertFalse(Failsafe.with(circuitBreaker).with(Fallback.of(false)).get(() -> true));

// Asynchronous
Future<Boolean> future1 = Failsafe.with(circuitBreaker).with(executor).getAsync(() -> true);
Asserts.assertThrows(future1::get, ExecutionException.class, CircuitBreakerOpenException.class);

// Asynchronous with fallback
Future<Boolean> future2 = Failsafe.with(circuitBreaker).with(executor).withFallback(false).getAsync(() -> true);
Future<Boolean> future2 = Failsafe.with(circuitBreaker).with(executor).with(Fallback.of(false)).getAsync(() -> true);
assertFalse(future2.get());

// Future
Expand All @@ -38,7 +35,7 @@ public void shouldHandleCircuitBreakerOpenException() throws Throwable {
// Future with fallback
Future<Boolean> future4 = Failsafe.with(circuitBreaker)
.with(executor)
.withFallback(false)
.with(Fallback.of(false))
.futureAsync(() -> CompletableFuture.completedFuture(false));
assertFalse(future4.get());
}
Expand Down

0 comments on commit 2186b3d

Please sign in to comment.