Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Merge pull request #75 from raghavan20/immutable-retryconfig
Browse files Browse the repository at this point in the history
CallExecutor to use immutable RetryConfig
  • Loading branch information
elennick authored Aug 19, 2018
2 parents 0eb3409 + fe5be0c commit d0635b3
Show file tree
Hide file tree
Showing 18 changed files with 464 additions and 303 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,10 +326,10 @@ new RetryConfigBuilder()
### CallExecutor
Executing your code with retry logic is as simple as instantiating a **CallExecutor** with your configuration and then calling execute:
Executing your code with retry logic is as simple as building a **CallExecutor** using **CallExecutorBuilder** with your configuration and then calling execute:
```java
new CallExecutor(config).execute(callable);
new CallExecutorBuilder.config(config).build().execute(callable);
```
The CallExecutor expects that your logic is wrapped in a **java.util.concurrent.Callable**.
Expand Down Expand Up @@ -426,12 +426,14 @@ executor.onCompletion(s -> {
Listeners can be chained together:

```java
new CallExecutor<>(config)
new CallExecutorBuilder<>()
.config(config)
.onSuccess(s -> System.out.println("Success!"))
.onCompletion(s -> System.out.println("Retry execution complete!"))
.onFailure(s -> System.out.println("Failed! All retries exhausted..."))
.afterFailedTry(s -> System.out.println("Try failed! Will try again in 0ms."))
.beforeNextTry(s -> System.out.println("Trying again..."))
.build()
.execute(callable);
```

Expand All @@ -442,7 +444,7 @@ Retry4j has some built in support for executing and retrying on one or more thre
in action with a single call:
```java
AsyncCallExecutor<Boolean> executor = new AsyncCallExecutor<>(config);
AsyncCallExecutor<Boolean> executor = new CallExecutorBuilder().config(config).buildAsync();
CompletableFuture<Status<Boolean>> future = executor.execute(callable);
Status<Boolean> status = future.get();
```
Expand All @@ -454,7 +456,7 @@ execution will not be blocked until `future.get()` is called (if it hasn't compl
This executor can also be used to trigger several Callable's in parallel:
```java
AsyncCallExecutor<Boolean> executor = new AsyncCallExecutor<>(retryOnAnyExceptionConfig);
AsyncCallExecutor<Boolean> executor = new CallExecutorBuilder().config(retryOnAnyExceptionConfig).buildAsync();
CompletableFuture<Status<Boolean>> future1 = executor.execute(callable1);
CompletableFuture<Status<Boolean>> future2 = executor.execute(callable2);
Expand All @@ -470,7 +472,7 @@ up.

```java
ExecutorService executorService = Executors.newFixedThreadPool(10);
new AsyncCallExecutor<>(config, executorService);
new CallExecutorBuilder().config(config).buildAsync(executorService);
```

You can register retry listeners and configuration on an `AsyncCallExecutor` in the same fashion as the normal,
Expand Down
55 changes: 25 additions & 30 deletions src/main/java/com/evanlennick/retry4j/AsyncCallExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,19 @@ public class AsyncCallExecutor<T> implements RetryExecutor<T, CompletableFuture<

private RetryListener<T> onCompletionListener;

public AsyncCallExecutor(RetryConfig config) {
this(config, null);
}

public AsyncCallExecutor(RetryConfig config, ExecutorService executorService) {
/**
* Use {@link CallExecutorBuilder} to build AsyncCallExecutor
*/
AsyncCallExecutor(RetryConfig config, ExecutorService executorService, RetryListener<T> afterFailedTryListener,
RetryListener<T> beforeNextTryListener, RetryListener<T> onFailureListener,
RetryListener<T> onSuccessListener, RetryListener<T> onCompletionListener) {
this.config = config;
this.executorService = executorService;
this.afterFailedTryListener = afterFailedTryListener;
this.beforeNextTryListener = beforeNextTryListener;
this.onFailureListener = onFailureListener;
this.onSuccessListener = onSuccessListener;
this.onCompletionListener = onCompletionListener;
}

@Override
Expand All @@ -45,13 +51,8 @@ public CompletableFuture<Status<T>> execute(Callable<T> callable) {

@Override
public CompletableFuture<Status<T>> execute(Callable<T> callable, String callName) {
CallExecutor<T> synchronousCallExecutor = new CallExecutor<>(config);

synchronousCallExecutor.afterFailedTry(afterFailedTryListener);
synchronousCallExecutor.beforeNextTry(beforeNextTryListener);
synchronousCallExecutor.onSuccess(onSuccessListener);
synchronousCallExecutor.onFailure(onFailureListener);
synchronousCallExecutor.onCompletion(onCompletionListener);
CallExecutor<T> synchronousCallExecutor = new CallExecutor<>(config, afterFailedTryListener,
beforeNextTryListener, onFailureListener, onSuccessListener, onCompletionListener);

CompletableFuture<Status<T>> completableFuture = new CompletableFuture<>();

Expand All @@ -75,34 +76,28 @@ private void executeFuture(Callable<T> callable, String callName, CallExecutor<T
}
}

public AsyncCallExecutor<T> afterFailedTry(RetryListener<T> listener) {
this.afterFailedTryListener = listener;
return this;
public RetryConfig getConfig() {
return config;
}

public AsyncCallExecutor<T> beforeNextTry(RetryListener<T> listener) {
this.beforeNextTryListener = listener;
return this;
public RetryListener<T> getAfterFailedTryListener() {
return afterFailedTryListener;
}

public AsyncCallExecutor<T> onCompletion(RetryListener<T> listener) {
this.onCompletionListener = listener;
return this;
public RetryListener<T> getBeforeNextTryListener() {
return beforeNextTryListener;
}

public AsyncCallExecutor<T> onSuccess(RetryListener<T> listener) {
this.onSuccessListener = listener;
return this;
public RetryListener<T> getOnFailureListener() {
return onFailureListener;
}

public AsyncCallExecutor<T> onFailure(RetryListener<T> listener) {
this.onFailureListener = listener;
return this;
public RetryListener<T> getOnSuccessListener() {
return onSuccessListener;
}

@Override
public void setConfig(RetryConfig config) {
this.config = config;
public RetryListener<T> getOnCompletionListener() {
return onCompletionListener;
}

public void setExecutorService(ExecutorService executorService) {
Expand Down
48 changes: 23 additions & 25 deletions src/main/java/com/evanlennick/retry4j/CallExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ public class CallExecutor<T> implements RetryExecutor<T, Status<T>> {

private Status<T> status = new Status<>();

public CallExecutor() {
this(new RetryConfigBuilder().fixedBackoff5Tries10Sec().build());
}

public CallExecutor(RetryConfig config) {
/**
* Use {@link CallExecutorBuilder} to build {@link CallExecutor}
*/
CallExecutor(RetryConfig config, RetryListener<T> afterFailedTryListener,
RetryListener<T> beforeNextTryListener, RetryListener<T> onFailureListener,
RetryListener<T> onSuccessListener, RetryListener<T> onCompletionListener) {
this.config = config;
this.afterFailedTryListener = afterFailedTryListener;
this.beforeNextTryListener = beforeNextTryListener;
this.onFailureListener = onFailureListener;
this.onSuccessListener = onSuccessListener;
this.onCompletionListener = onCompletionListener;
this.status.setId(UUID.randomUUID().toString());
}

Expand Down Expand Up @@ -232,36 +238,28 @@ private Set<Class<?>> getExceptionCauses(Exception exception) {
}
return causes;
}

@Override
public void setConfig(RetryConfig config) {
logger.trace("Set config on retry4j executor {}", config);
this.config = config;
public RetryConfig getConfig() {
return config;
}

public CallExecutor<T> afterFailedTry(RetryListener<T> listener) {
this.afterFailedTryListener = listener;
return this;
public RetryListener<T> getAfterFailedTryListener() {
return afterFailedTryListener;
}

public CallExecutor<T> beforeNextTry(RetryListener<T> listener) {
this.beforeNextTryListener = listener;
return this;
public RetryListener<T> getBeforeNextTryListener() {
return beforeNextTryListener;
}

public CallExecutor<T> onCompletion(RetryListener<T> listener) {
this.onCompletionListener = listener;
return this;
public RetryListener<T> getOnFailureListener() {
return onFailureListener;
}

public CallExecutor<T> onSuccess(RetryListener<T> listener) {
this.onSuccessListener = listener;
return this;
public RetryListener<T> getOnSuccessListener() {
return onSuccessListener;
}

public CallExecutor<T> onFailure(RetryListener<T> listener) {
this.onFailureListener = listener;
return this;
public RetryListener<T> getOnCompletionListener() {
return onCompletionListener;
}

@Override
Expand Down
66 changes: 66 additions & 0 deletions src/main/java/com/evanlennick/retry4j/CallExecutorBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.evanlennick.retry4j;

import com.evanlennick.retry4j.config.RetryConfig;
import com.evanlennick.retry4j.config.RetryConfigBuilder;
import com.evanlennick.retry4j.listener.RetryListener;

import java.util.concurrent.ExecutorService;

public class CallExecutorBuilder<T> {

public static final RetryConfig DEFAULT_RETRY_CONFIG = new RetryConfigBuilder().fixedBackoff5Tries10Sec().build();
private RetryConfig retryConfig = DEFAULT_RETRY_CONFIG;
private RetryListener afterFailedTryListener;
private RetryListener beforeNextTryListener;
private RetryListener onSuccessListener;
private RetryListener onFailureListener;
private RetryListener onCompletionListener;

public CallExecutorBuilder() {
}

public CallExecutorBuilder config(RetryConfig retryConfig) {
this.retryConfig = retryConfig;
return this;
}

public CallExecutorBuilder onCompletionListener(RetryListener listener) {
this.onCompletionListener = listener;
return this;
}

public CallExecutorBuilder onSuccessListener(RetryListener listener) {
this.onSuccessListener = listener;
return this;
}

public CallExecutorBuilder onFailureListener(RetryListener listener) {
this.onFailureListener = listener;
return this;
}

public CallExecutorBuilder beforeNextTryListener(RetryListener listener) {
this.beforeNextTryListener = listener;
return this;
}

public CallExecutorBuilder afterFailedTryListener(RetryListener listener) {
this.afterFailedTryListener = listener;
return this;
}

public CallExecutor<T> build() {
return new CallExecutor(retryConfig, afterFailedTryListener, beforeNextTryListener,
onFailureListener, onSuccessListener, onCompletionListener);
}

public AsyncCallExecutor<T> buildAsync() {
return new AsyncCallExecutor(retryConfig, null, afterFailedTryListener, beforeNextTryListener,
onFailureListener, onSuccessListener, onCompletionListener);
}

public AsyncCallExecutor<T> buildAsync(ExecutorService executorService) {
return new AsyncCallExecutor(retryConfig, executorService, afterFailedTryListener, beforeNextTryListener,
onFailureListener, onSuccessListener, onCompletionListener);
}
}
2 changes: 0 additions & 2 deletions src/main/java/com/evanlennick/retry4j/RetryExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,4 @@ public interface RetryExecutor<T, S> {

S execute(Callable<T> callable, String callName) throws RetriesExhaustedException, UnexpectedException;

void setConfig(RetryConfig config);

}
Loading

0 comments on commit d0635b3

Please sign in to comment.