Skip to content

Commit

Permalink
Misc improvements
Browse files Browse the repository at this point in the history
- Removed Failsafe.with(Policy[])
- Removed volatile from event listener members. This can be added in the future if these ever become mutable after a policy is built.
  • Loading branch information
jhalterman committed Nov 11, 2021
1 parent f66aa2d commit 25161a9
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 54 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Expand Up @@ -8,10 +8,11 @@ This release introduces breaking changes to the API:
#### General

- All files have been moved to the `dev.failsafe` package. Be sure to update your imports.
- `Failsafe.with(P[] policies)` was removed.

#### Policies

- All policies are now threadsafe and use a builder API. The configuration methods available in the builder are mostly the same as previously with the 2.x policies. Some notes:
- All policies now use a builder API. The configuration methods available in the builder are mostly the same as previously with the 2.x policies. Some notes:
- A policy builder can be created via `builder()`.
- `RetryPolicy` and `CircuitBreaker` can be constructed with default values using `ofDefaults()`.
- Policy configuration is accessible via a `getConfig()`.
Expand Down Expand Up @@ -57,11 +58,11 @@ The following changes effect the SPI classes, for users who are extending Failsa

### Improvements

- Issue #47 and #201 - All policies and policy config classes are now threadsafe. Policy builders are not threadsafe. These are clearly noted in the Javadocs.
- Issue #292 - Created an extensible Policy SPI.
- Issue #254 - Added an explicit `compose` method to `FailsafeExecutor`.
- Issue #293 - Added `RetryPolicyBuilder.withBackoff(Duration, Duration)` and `.withDelay(Duration, Duration)`.
- Issue #221 - `Executor` instances configured via `FailsafeExecutor.with(Executor)` are now used on all executions, including sync executions, and can be used in conjunction with a separately configured `ExecutorService` or `Scheduler` for async executions.
- Issue #47 - Thread safety is now clearly documented in the policy, policy builder, and policy config classes. Policy and policy config classes are threadsafe. Policy builder classes are not threadsafe.
- Added `FailsafeExecutor.getPolicies()`.

# 2.4.4
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/dev/failsafe/CircuitBreakerConfig.java
Expand Up @@ -43,9 +43,9 @@ public class CircuitBreakerConfig<R> extends DelayablePolicyConfig<R> {
int successThresholdingCapacity;

// Listeners
volatile EventListener<CircuitBreakerStateChangedEvent> openListener;
volatile EventListener<CircuitBreakerStateChangedEvent> halfOpenListener;
volatile EventListener<CircuitBreakerStateChangedEvent> closeListener;
EventListener<CircuitBreakerStateChangedEvent> openListener;
EventListener<CircuitBreakerStateChangedEvent> halfOpenListener;
EventListener<CircuitBreakerStateChangedEvent> closeListener;

CircuitBreakerConfig() {
}
Expand Down Expand Up @@ -161,7 +161,7 @@ public int getSuccessThresholdingCapacity() {
/**
* Returns the open event listener.
*
* @see CircuitBreakerListeners#onOpen(EventListener)
* @see CircuitBreakerBuilder#onOpen(EventListener)
*/
public EventListener<CircuitBreakerStateChangedEvent> getOpenListener() {
return openListener;
Expand All @@ -170,7 +170,7 @@ public EventListener<CircuitBreakerStateChangedEvent> getOpenListener() {
/**
* Returns the half-open event listener.
*
* @see CircuitBreakerListeners#onHalfOpen(EventListener)
* @see CircuitBreakerBuilder#onHalfOpen(EventListener)
*/
public EventListener<CircuitBreakerStateChangedEvent> getHalfOpenListener() {
return halfOpenListener;
Expand All @@ -179,7 +179,7 @@ public EventListener<CircuitBreakerStateChangedEvent> getHalfOpenListener() {
/**
* Returns the close event listener.
*
* @see CircuitBreakerListeners#onClose(EventListener)
* @see CircuitBreakerBuilder#onClose(EventListener)
*/
public EventListener<CircuitBreakerStateChangedEvent> getCloseListener() {
return closeListener;
Expand Down
33 changes: 0 additions & 33 deletions src/main/java/dev/failsafe/Failsafe.java
Expand Up @@ -18,7 +18,6 @@
import dev.failsafe.internal.util.Assert;
import dev.failsafe.internal.util.Lists;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

Expand Down Expand Up @@ -64,38 +63,6 @@ public static <R, P extends Policy<R>> FailsafeExecutor<R> with(P outerPolicy, P
return new FailsafeExecutor<>(Lists.of(outerPolicy, policies));
}

/**
* Creates and returns a new {@link FailsafeExecutor} instance that will handle failures according to the given {@code
* policies}. The {@code policies} are composed around an execution and will handle execution results in reverse, with
* the last policy being applied first. For example, consider:
* <p>
* <pre>
* Failsafe.with(fallback, retryPolicy, circuitBreaker).get(supplier);
* </pre>
* </p>
* This results in the following internal composition when executing the {@code supplier} and handling its result:
* <p>
* <pre>
* Fallback(RetryPolicy(CircuitBreaker(Supplier)))
* </pre>
* </p>
* This means the {@code CircuitBreaker} is first to evaluate the {@code Supplier}'s result, then the {@code
* RetryPolicy}, then the {@code Fallback}. Each policy makes its own determination as to whether the result
* represents a failure. This allows different policies to be used for handling different types of failures.
*
* @param <R> result type
* @param <P> policy type
* @throws NullPointerException if {@code policies} is null
* @throws IllegalArgumentException if {@code policies} is empty
* @deprecated This will be removed in 3.0. Use {@link #with(Policy, Policy[])} instead
*/
@Deprecated
public static <R, P extends Policy<R>> FailsafeExecutor<R> with(P[] policies) {
Assert.notNull(policies, "policies");
Assert.isTrue(policies.length > 0, "At least one policy must be supplied");
return new FailsafeExecutor<>(Arrays.asList(policies));
}

/**
* Creates and returns a new {@link FailsafeExecutor} instance that will handle failures according to the given {@code
* policies}. The {@code policies} are composed around an execution and will handle execution results in reverse, with
Expand Down
1 change: 0 additions & 1 deletion src/main/java/dev/failsafe/FailsafeExecutor.java
Expand Up @@ -24,7 +24,6 @@
import dev.failsafe.spi.ExecutionResult;
import dev.failsafe.spi.FailsafeFuture;
import dev.failsafe.spi.Scheduler;
import dev.failsafe.function.*;

import java.util.ArrayList;
import java.util.List;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/dev/failsafe/FallbackConfig.java
Expand Up @@ -40,7 +40,7 @@ public class FallbackConfig<R> extends FailurePolicyConfig<R> {
boolean async;

// Listeners
volatile EventListener<ExecutionAttemptedEvent<R>> failedAttemptListener;
EventListener<ExecutionAttemptedEvent<R>> failedAttemptListener;

FallbackConfig() {
}
Expand Down Expand Up @@ -103,7 +103,7 @@ public boolean isAsync() {
/**
* Returns the failed attempt event listener.
*
* @see FallbackListeners#onFailedAttempt(CheckedConsumer)
* @see FallbackBuilder#onFailedAttempt(EventListener)
*/
public EventListener<ExecutionAttemptedEvent<R>> getFailedAttemptListener() {
return failedAttemptListener;
Expand Down
20 changes: 10 additions & 10 deletions src/main/java/dev/failsafe/RetryPolicyConfig.java
Expand Up @@ -49,11 +49,11 @@ public class RetryPolicyConfig<R> extends DelayablePolicyConfig<R> {
List<BiPredicate<R, Throwable>> abortConditions;

// Listeners
volatile EventListener<ExecutionCompletedEvent<R>> abortListener;
volatile EventListener<ExecutionAttemptedEvent<R>> failedAttemptListener;
volatile EventListener<ExecutionCompletedEvent<R>> retriesExceededListener;
volatile EventListener<ExecutionAttemptedEvent<R>> retryListener;
volatile EventListener<ExecutionScheduledEvent<R>> retryScheduledListener;
EventListener<ExecutionCompletedEvent<R>> abortListener;
EventListener<ExecutionAttemptedEvent<R>> failedAttemptListener;
EventListener<ExecutionCompletedEvent<R>> retriesExceededListener;
EventListener<ExecutionAttemptedEvent<R>> retryListener;
EventListener<ExecutionScheduledEvent<R>> retryScheduledListener;

RetryPolicyConfig() {
}
Expand Down Expand Up @@ -210,7 +210,7 @@ public int getMaxRetries() {
/**
* Returns the abort event listener.
*
* @see RetryPolicyListeners#onAbort(EventListener)
* @see RetryPolicyBuilder#onAbort(EventListener)
*/
public EventListener<ExecutionCompletedEvent<R>> getAbortListener() {
return abortListener;
Expand All @@ -219,7 +219,7 @@ public EventListener<ExecutionCompletedEvent<R>> getAbortListener() {
/**
* Returns the failed attempt event listener.
*
* @see RetryPolicyListeners#onFailedAttempt(EventListener)
* @see RetryPolicyBuilder#onFailedAttempt(EventListener)
*/
public EventListener<ExecutionAttemptedEvent<R>> getFailedAttemptListener() {
return failedAttemptListener;
Expand All @@ -228,7 +228,7 @@ public EventListener<ExecutionAttemptedEvent<R>> getFailedAttemptListener() {
/**
* Returns the retries exceeded event listener.
*
* @see RetryPolicyListeners#onRetriesExceeded(EventListener)
* @see RetryPolicyBuilder#onRetriesExceeded(EventListener)
*/
public EventListener<ExecutionCompletedEvent<R>> getRetriesExceededListener() {
return retriesExceededListener;
Expand All @@ -237,7 +237,7 @@ public EventListener<ExecutionCompletedEvent<R>> getRetriesExceededListener() {
/**
* Returns the retry event listener.
*
* @see RetryPolicyListeners#onRetry(EventListener)
* @see RetryPolicyBuilder#onRetry(EventListener)
*/
public EventListener<ExecutionAttemptedEvent<R>> getRetryListener() {
return retryListener;
Expand All @@ -246,7 +246,7 @@ public EventListener<ExecutionAttemptedEvent<R>> getRetryListener() {
/**
* Returns the retry scheduled event listener.
*
* @see RetryPolicyListeners#onRetryScheduled(EventListener)
* @see RetryPolicyBuilder#onRetryScheduled(EventListener)
*/
public EventListener<ExecutionScheduledEvent<R>> getRetryScheduledListener() {
return retryScheduledListener;
Expand Down

0 comments on commit 25161a9

Please sign in to comment.