Skip to content

Commit 5ef8514

Browse files
committed
Misc improvements
- 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.
1 parent f66aa2d commit 5ef8514

File tree

6 files changed

+22
-54
lines changed

6 files changed

+22
-54
lines changed

CHANGELOG.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ This release introduces breaking changes to the API:
88
#### General
99

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

1213
#### Policies
1314

14-
- 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:
15+
- 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:
1516
- A policy builder can be created via `builder()`.
1617
- `RetryPolicy` and `CircuitBreaker` can be constructed with default values using `ofDefaults()`.
1718
- Policy configuration is accessible via a `getConfig()`.
@@ -57,11 +58,12 @@ The following changes effect the SPI classes, for users who are extending Failsa
5758

5859
### Improvements
5960

61+
- Issue #47 - All policies and policy config classes are now threadsafe. Policy builders are not threadsafe.
62+
- Issue #201 - Thread safety is clearly documented in policy, policy config, and policy builder classes.
6063
- Issue #292 - Created an extensible Policy SPI.
6164
- Issue #254 - Added an explicit `compose` method to `FailsafeExecutor`.
6265
- Issue #293 - Added `RetryPolicyBuilder.withBackoff(Duration, Duration)` and `.withDelay(Duration, Duration)`.
6366
- 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.
64-
- 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.
6567
- Added `FailsafeExecutor.getPolicies()`.
6668

6769
# 2.4.4

src/main/java/dev/failsafe/CircuitBreakerConfig.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ public class CircuitBreakerConfig<R> extends DelayablePolicyConfig<R> {
4343
int successThresholdingCapacity;
4444

4545
// Listeners
46-
volatile EventListener<CircuitBreakerStateChangedEvent> openListener;
47-
volatile EventListener<CircuitBreakerStateChangedEvent> halfOpenListener;
48-
volatile EventListener<CircuitBreakerStateChangedEvent> closeListener;
46+
EventListener<CircuitBreakerStateChangedEvent> openListener;
47+
EventListener<CircuitBreakerStateChangedEvent> halfOpenListener;
48+
EventListener<CircuitBreakerStateChangedEvent> closeListener;
4949

5050
CircuitBreakerConfig() {
5151
}
@@ -161,7 +161,7 @@ public int getSuccessThresholdingCapacity() {
161161
/**
162162
* Returns the open event listener.
163163
*
164-
* @see CircuitBreakerListeners#onOpen(EventListener)
164+
* @see CircuitBreakerBuilder#onOpen(EventListener)
165165
*/
166166
public EventListener<CircuitBreakerStateChangedEvent> getOpenListener() {
167167
return openListener;
@@ -170,7 +170,7 @@ public EventListener<CircuitBreakerStateChangedEvent> getOpenListener() {
170170
/**
171171
* Returns the half-open event listener.
172172
*
173-
* @see CircuitBreakerListeners#onHalfOpen(EventListener)
173+
* @see CircuitBreakerBuilder#onHalfOpen(EventListener)
174174
*/
175175
public EventListener<CircuitBreakerStateChangedEvent> getHalfOpenListener() {
176176
return halfOpenListener;
@@ -179,7 +179,7 @@ public EventListener<CircuitBreakerStateChangedEvent> getHalfOpenListener() {
179179
/**
180180
* Returns the close event listener.
181181
*
182-
* @see CircuitBreakerListeners#onClose(EventListener)
182+
* @see CircuitBreakerBuilder#onClose(EventListener)
183183
*/
184184
public EventListener<CircuitBreakerStateChangedEvent> getCloseListener() {
185185
return closeListener;

src/main/java/dev/failsafe/Failsafe.java

-33
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import dev.failsafe.internal.util.Assert;
1919
import dev.failsafe.internal.util.Lists;
2020

21-
import java.util.Arrays;
2221
import java.util.Collections;
2322
import java.util.List;
2423

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

67-
/**
68-
* Creates and returns a new {@link FailsafeExecutor} instance that will handle failures according to the given {@code
69-
* policies}. The {@code policies} are composed around an execution and will handle execution results in reverse, with
70-
* the last policy being applied first. For example, consider:
71-
* <p>
72-
* <pre>
73-
* Failsafe.with(fallback, retryPolicy, circuitBreaker).get(supplier);
74-
* </pre>
75-
* </p>
76-
* This results in the following internal composition when executing the {@code supplier} and handling its result:
77-
* <p>
78-
* <pre>
79-
* Fallback(RetryPolicy(CircuitBreaker(Supplier)))
80-
* </pre>
81-
* </p>
82-
* This means the {@code CircuitBreaker} is first to evaluate the {@code Supplier}'s result, then the {@code
83-
* RetryPolicy}, then the {@code Fallback}. Each policy makes its own determination as to whether the result
84-
* represents a failure. This allows different policies to be used for handling different types of failures.
85-
*
86-
* @param <R> result type
87-
* @param <P> policy type
88-
* @throws NullPointerException if {@code policies} is null
89-
* @throws IllegalArgumentException if {@code policies} is empty
90-
* @deprecated This will be removed in 3.0. Use {@link #with(Policy, Policy[])} instead
91-
*/
92-
@Deprecated
93-
public static <R, P extends Policy<R>> FailsafeExecutor<R> with(P[] policies) {
94-
Assert.notNull(policies, "policies");
95-
Assert.isTrue(policies.length > 0, "At least one policy must be supplied");
96-
return new FailsafeExecutor<>(Arrays.asList(policies));
97-
}
98-
9966
/**
10067
* Creates and returns a new {@link FailsafeExecutor} instance that will handle failures according to the given {@code
10168
* policies}. The {@code policies} are composed around an execution and will handle execution results in reverse, with

src/main/java/dev/failsafe/FailsafeExecutor.java

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import dev.failsafe.spi.ExecutionResult;
2525
import dev.failsafe.spi.FailsafeFuture;
2626
import dev.failsafe.spi.Scheduler;
27-
import dev.failsafe.function.*;
2827

2928
import java.util.ArrayList;
3029
import java.util.List;

src/main/java/dev/failsafe/FallbackConfig.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class FallbackConfig<R> extends FailurePolicyConfig<R> {
4040
boolean async;
4141

4242
// Listeners
43-
volatile EventListener<ExecutionAttemptedEvent<R>> failedAttemptListener;
43+
EventListener<ExecutionAttemptedEvent<R>> failedAttemptListener;
4444

4545
FallbackConfig() {
4646
}
@@ -103,7 +103,7 @@ public boolean isAsync() {
103103
/**
104104
* Returns the failed attempt event listener.
105105
*
106-
* @see FallbackListeners#onFailedAttempt(CheckedConsumer)
106+
* @see FallbackBuilder#onFailedAttempt(EventListener)
107107
*/
108108
public EventListener<ExecutionAttemptedEvent<R>> getFailedAttemptListener() {
109109
return failedAttemptListener;

src/main/java/dev/failsafe/RetryPolicyConfig.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ public class RetryPolicyConfig<R> extends DelayablePolicyConfig<R> {
4949
List<BiPredicate<R, Throwable>> abortConditions;
5050

5151
// Listeners
52-
volatile EventListener<ExecutionCompletedEvent<R>> abortListener;
53-
volatile EventListener<ExecutionAttemptedEvent<R>> failedAttemptListener;
54-
volatile EventListener<ExecutionCompletedEvent<R>> retriesExceededListener;
55-
volatile EventListener<ExecutionAttemptedEvent<R>> retryListener;
56-
volatile EventListener<ExecutionScheduledEvent<R>> retryScheduledListener;
52+
EventListener<ExecutionCompletedEvent<R>> abortListener;
53+
EventListener<ExecutionAttemptedEvent<R>> failedAttemptListener;
54+
EventListener<ExecutionCompletedEvent<R>> retriesExceededListener;
55+
EventListener<ExecutionAttemptedEvent<R>> retryListener;
56+
EventListener<ExecutionScheduledEvent<R>> retryScheduledListener;
5757

5858
RetryPolicyConfig() {
5959
}
@@ -210,7 +210,7 @@ public int getMaxRetries() {
210210
/**
211211
* Returns the abort event listener.
212212
*
213-
* @see RetryPolicyListeners#onAbort(EventListener)
213+
* @see RetryPolicyBuilder#onAbort(EventListener)
214214
*/
215215
public EventListener<ExecutionCompletedEvent<R>> getAbortListener() {
216216
return abortListener;
@@ -219,7 +219,7 @@ public EventListener<ExecutionCompletedEvent<R>> getAbortListener() {
219219
/**
220220
* Returns the failed attempt event listener.
221221
*
222-
* @see RetryPolicyListeners#onFailedAttempt(EventListener)
222+
* @see RetryPolicyBuilder#onFailedAttempt(EventListener)
223223
*/
224224
public EventListener<ExecutionAttemptedEvent<R>> getFailedAttemptListener() {
225225
return failedAttemptListener;
@@ -228,7 +228,7 @@ public EventListener<ExecutionAttemptedEvent<R>> getFailedAttemptListener() {
228228
/**
229229
* Returns the retries exceeded event listener.
230230
*
231-
* @see RetryPolicyListeners#onRetriesExceeded(EventListener)
231+
* @see RetryPolicyBuilder#onRetriesExceeded(EventListener)
232232
*/
233233
public EventListener<ExecutionCompletedEvent<R>> getRetriesExceededListener() {
234234
return retriesExceededListener;
@@ -237,7 +237,7 @@ public EventListener<ExecutionCompletedEvent<R>> getRetriesExceededListener() {
237237
/**
238238
* Returns the retry event listener.
239239
*
240-
* @see RetryPolicyListeners#onRetry(EventListener)
240+
* @see RetryPolicyBuilder#onRetry(EventListener)
241241
*/
242242
public EventListener<ExecutionAttemptedEvent<R>> getRetryListener() {
243243
return retryListener;
@@ -246,7 +246,7 @@ public EventListener<ExecutionAttemptedEvent<R>> getRetryListener() {
246246
/**
247247
* Returns the retry scheduled event listener.
248248
*
249-
* @see RetryPolicyListeners#onRetryScheduled(EventListener)
249+
* @see RetryPolicyBuilder#onRetryScheduled(EventListener)
250250
*/
251251
public EventListener<ExecutionScheduledEvent<R>> getRetryScheduledListener() {
252252
return retryScheduledListener;

0 commit comments

Comments
 (0)