Skip to content

Commit

Permalink
Fixes ReactiveX#10: Reorders arguments in decorator methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Winkler committed Nov 22, 2016
1 parent 1d5ca9c commit 0bad9f5
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 14 deletions.
Empty file modified gradlew
100644 → 100755
Empty file.
166 changes: 166 additions & 0 deletions src/main/java/javaslang/circuitbreaker/CircuitBreaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,10 @@ interface Metrics {
*
* @param supplier the original supplier
* @param circuitBreaker the CircuitBreaker
*
* @return a supplier which is secured by a CircuitBreaker.
*/
@Deprecated
static <T> Try.CheckedSupplier<T> decorateCheckedSupplier(Try.CheckedSupplier<T> supplier, CircuitBreaker circuitBreaker){
return () -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
Expand All @@ -173,13 +175,38 @@ static <T> Try.CheckedSupplier<T> decorateCheckedSupplier(Try.CheckedSupplier<T>
};
}


/**
* Creates a supplier which is secured by a CircuitBreaker.
*
* @param circuitBreaker the CircuitBreaker
* @param supplier the original supplier
*
* @return a supplier which is secured by a CircuitBreaker.
*/
static <T> Try.CheckedSupplier<T> decorateCheckedSupplier(CircuitBreaker circuitBreaker, Try.CheckedSupplier<T> supplier){
return () -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
try {
T returnValue = supplier.get();
circuitBreaker.recordSuccess();
return returnValue;
} catch (Throwable throwable) {
circuitBreaker.recordFailure(throwable);
throw throwable;
}
};
}

/**
* Creates a runnable which is secured by a CircuitBreaker.
*
* @param runnable the original runnable
* @param circuitBreaker the CircuitBreaker
*
* @return a runnable which is secured by a CircuitBreaker.
*/
@Deprecated
static Try.CheckedRunnable decorateCheckedRunnable(Try.CheckedRunnable runnable, CircuitBreaker circuitBreaker){
return () -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
Expand All @@ -193,13 +220,36 @@ static Try.CheckedRunnable decorateCheckedRunnable(Try.CheckedRunnable runnable,
};
}

/**
* Creates a runnable which is secured by a CircuitBreaker.
*
* @param circuitBreaker the CircuitBreaker
* @param runnable the original runnable
* @return a runnable which is secured by a CircuitBreaker.
*/
static Try.CheckedRunnable decorateCheckedRunnable(CircuitBreaker circuitBreaker, Try.CheckedRunnable runnable){
return () -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
try{
runnable.run();
circuitBreaker.recordSuccess();
} catch (Throwable throwable){
circuitBreaker.recordFailure(throwable);
throw throwable;
}
};
}

/**
* Creates a supplier which is secured by a CircuitBreaker.
*
* @param supplier the original supplier
* @param circuitBreaker the CircuitBreaker
*
* @return a supplier which is secured by a CircuitBreaker.
*/
@Deprecated
static <T> Supplier<T> decorateSupplier(Supplier<T> supplier, CircuitBreaker circuitBreaker){
return () -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
Expand All @@ -214,13 +264,37 @@ static <T> Supplier<T> decorateSupplier(Supplier<T> supplier, CircuitBreaker cir
};
}

/**
* Creates a supplier which is secured by a CircuitBreaker.
*
* @param circuitBreaker the CircuitBreaker
* @param supplier the original supplier
*
* @return a supplier which is secured by a CircuitBreaker.
*/
static <T> Supplier<T> decorateSupplier(CircuitBreaker circuitBreaker, Supplier<T> supplier){
return () -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
try {
T returnValue = supplier.get();
circuitBreaker.recordSuccess();
return returnValue;
} catch (Throwable throwable) {
circuitBreaker.recordFailure(throwable);
throw throwable;
}
};
}

/**
* Creates a consumer which is secured by a CircuitBreaker.
*
* @param consumer the original consumer
* @param circuitBreaker the CircuitBreaker
*
* @return a consumer which is secured by a CircuitBreaker.
*/
@Deprecated
static <T> Consumer<T> decorateConsumer(Consumer<T> consumer, CircuitBreaker circuitBreaker){
return (t) -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
Expand All @@ -234,13 +308,36 @@ static <T> Consumer<T> decorateConsumer(Consumer<T> consumer, CircuitBreaker cir
};
}

/**
* Creates a consumer which is secured by a CircuitBreaker.
* @param circuitBreaker the CircuitBreaker
* @param consumer the original consumer
*
* @return a consumer which is secured by a CircuitBreaker.
*/
static <T> Consumer<T> decorateConsumer(CircuitBreaker circuitBreaker, Consumer<T> consumer){
return (t) -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
try {
consumer.accept(t);
circuitBreaker.recordSuccess();
} catch (Throwable throwable) {
circuitBreaker.recordFailure(throwable);
throw throwable;
}
};
}

/**
* Creates a runnable which is secured by a CircuitBreaker.
*
* @param runnable the original runnable
* @param circuitBreaker the CircuitBreaker
*
* @return a runnable which is secured by a CircuitBreaker.
*/
@Deprecated
static Runnable decorateRunnable(Runnable runnable, CircuitBreaker circuitBreaker){
return () -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
Expand All @@ -254,13 +351,36 @@ static Runnable decorateRunnable(Runnable runnable, CircuitBreaker circuitBreake
};
}

/**
* Creates a runnable which is secured by a CircuitBreaker.
*
* @param circuitBreaker the CircuitBreaker
* @param runnable the original runnable
*
* @return a runnable which is secured by a CircuitBreaker.
*/
static Runnable decorateRunnable(CircuitBreaker circuitBreaker, Runnable runnable){
return () -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
try{
runnable.run();
circuitBreaker.recordSuccess();
} catch (Throwable throwable){
circuitBreaker.recordFailure(throwable);
throw throwable;
}
};
}

/**
* Creates a function which is secured by a CircuitBreaker.
*
* @param function the original function
* @param circuitBreaker the CircuitBreaker
*
* @return a function which is secured by a CircuitBreaker.
*/
@Deprecated
static <T, R> Function<T, R> decorateFunction(Function<T, R> function, CircuitBreaker circuitBreaker){
return (T t) -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
Expand All @@ -275,13 +395,37 @@ static <T, R> Function<T, R> decorateFunction(Function<T, R> function, CircuitBr
};
}

/**
* Creates a function which is secured by a CircuitBreaker.
* @param circuitBreaker the CircuitBreaker
* @param function the original function
*
* @return a function which is secured by a CircuitBreaker.
*/
static <T, R> Function<T, R> decorateFunction(CircuitBreaker circuitBreaker, Function<T, R> function){
return (T t) -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
try{
R returnValue = function.apply(t);
circuitBreaker.recordSuccess();
return returnValue;
} catch (Throwable throwable){
circuitBreaker.recordFailure(throwable);
throw throwable;
}
};
}

/**
* Creates a function which is secured by a CircuitBreaker.
*
* @param function the original function
* @param circuitBreaker the CircuitBreaker
*
* @return a function which is secured by a CircuitBreaker.
*/
@Deprecated
static <T, R> Try.CheckedFunction<T, R> decorateCheckedFunction(Try.CheckedFunction<T, R> function, CircuitBreaker circuitBreaker){
return (T t) -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
Expand All @@ -295,4 +439,26 @@ static <T, R> Try.CheckedFunction<T, R> decorateCheckedFunction(Try.CheckedFunct
}
};
}

/**
* Creates a function which is secured by a CircuitBreaker.
*
* @param circuitBreaker the CircuitBreaker
* @param function the original function
*
* @return a function which is secured by a CircuitBreaker.
*/
static <T, R> Try.CheckedFunction<T, R> decorateCheckedFunction(CircuitBreaker circuitBreaker, Try.CheckedFunction<T, R> function){
return (T t) -> {
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
try{
R returnValue = function.apply(t);
circuitBreaker.recordSuccess();
return returnValue;
} catch (Throwable throwable){
circuitBreaker.recordFailure(throwable);
throw throwable;
}
};
}
}
28 changes: 14 additions & 14 deletions src/test/java/javaslang/circuitbreaker/CircuitBreakerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ public void shouldReturnFailureWithCircuitBreakerOpenException() {
assertThat(circuitBreaker.getState()).isEqualTo(CircuitBreaker.State.OPEN);

//When
Try.CheckedRunnable checkedRunnable = CircuitBreaker.decorateCheckedRunnable(() -> {
Try.CheckedRunnable checkedRunnable = CircuitBreaker.decorateCheckedRunnable(circuitBreaker, () -> {
throw new RuntimeException("BAM!");
}, circuitBreaker);
});
Try result = Try.run(checkedRunnable);

//Then
Expand All @@ -75,9 +75,9 @@ public void shouldReturnFailureWithRuntimeException() {
assertThat(circuitBreaker.getState()).isEqualTo(CircuitBreaker.State.CLOSED);

//When
Try.CheckedRunnable checkedRunnable = CircuitBreaker.decorateCheckedRunnable(() -> {
Try.CheckedRunnable checkedRunnable = CircuitBreaker.decorateCheckedRunnable(circuitBreaker, () -> {
throw new RuntimeException("BAM!");
}, circuitBreaker);
});
Try result = Try.run(checkedRunnable);

//Then
Expand Down Expand Up @@ -106,9 +106,9 @@ public void shouldNotRecordIOExceptionAsAFailure() {
assertThat(circuitBreaker.getState()).isEqualTo(CircuitBreaker.State.CLOSED);

//When
Try.CheckedRunnable checkedRunnable = CircuitBreaker.decorateCheckedRunnable(() -> {
Try.CheckedRunnable checkedRunnable = CircuitBreaker.decorateCheckedRunnable(circuitBreaker, () -> {
throw new SocketTimeoutException("BAM!");
}, circuitBreaker);
});
Try result = Try.run(checkedRunnable);

//Then
Expand All @@ -127,7 +127,7 @@ public void shouldReturnSuccess() {
assertThat(circuitBreaker.getState()).isEqualTo(CircuitBreaker.State.CLOSED);

//When
Supplier<String> checkedSupplier = CircuitBreaker.decorateSupplier(() -> "Hello world", circuitBreaker);
Supplier<String> checkedSupplier = CircuitBreaker.decorateSupplier(circuitBreaker, () -> "Hello world");

//Then
assertThat(checkedSupplier.get()).isEqualTo("Hello world");
Expand All @@ -141,9 +141,9 @@ public void shouldInvokeRecoverFunction() {
CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker("testName");

// When I decorate my function and invoke the decorated function
Try.CheckedSupplier<String> checkedSupplier = CircuitBreaker.decorateCheckedSupplier(() -> {
Try.CheckedSupplier<String> checkedSupplier = CircuitBreaker.decorateCheckedSupplier(circuitBreaker, () -> {
throw new RuntimeException("BAM!");
}, circuitBreaker);
});
Try<String> result = Try.of(checkedSupplier)
.recover(throwable -> "Hello Recovery");

Expand All @@ -163,7 +163,7 @@ public void shouldInvokeMap() {

// When I decorate my function
Try.CheckedSupplier<String> decoratedSupplier = CircuitBreaker
.decorateCheckedSupplier(() -> "This can be any method which returns: 'Hello", circuitBreaker);
.decorateCheckedSupplier(circuitBreaker, () -> "This can be any method which returns: 'Hello");

// and chain an other function with map
Try<String> result = Try.of(decoratedSupplier)
Expand Down Expand Up @@ -197,7 +197,7 @@ public void shouldThrowCircuitBreakerOpenException() {
assertThat(circuitBreaker.getState()).isEqualTo(CircuitBreaker.State.OPEN);

// When I decorate my function and invoke the decorated function
Try<String> result = Try.of(CircuitBreaker.decorateCheckedSupplier(() -> "Hello", circuitBreaker))
Try<String> result = Try.of(CircuitBreaker.decorateCheckedSupplier(circuitBreaker, () -> "Hello"))
.map(value -> value + " world");

// Then the call fails, because CircuitBreaker is OPEN
Expand All @@ -217,7 +217,7 @@ public void shouldInvokeAsyncApply() throws ExecutionException, InterruptedExcep

// When
Supplier<String> decoratedSupplier = CircuitBreaker
.decorateSupplier(() -> "This can be any method which returns: 'Hello", circuitBreaker);
.decorateSupplier(circuitBreaker, () -> "This can be any method which returns: 'Hello");

CompletableFuture<String> future = CompletableFuture.supplyAsync(decoratedSupplier)
.thenApply(value -> value + " world'");
Expand All @@ -238,10 +238,10 @@ public void shouldChainDecoratedFunctions() throws ExecutionException, Interrupt

// When I create a Supplier and a Function which are decorated by different CircuitBreakers
Try.CheckedSupplier<String> decoratedSupplier = CircuitBreaker
.decorateCheckedSupplier(() -> "Hello", circuitBreaker);
.decorateCheckedSupplier(circuitBreaker, () -> "Hello");

Try.CheckedFunction<String, String> decoratedFunction = CircuitBreaker
.decorateCheckedFunction((input) -> input + " world", anotherCircuitBreaker);
.decorateCheckedFunction(anotherCircuitBreaker, (input) -> input + " world");

// and I chain a function with map
Try<String> result = Try.of(decoratedSupplier)
Expand Down

0 comments on commit 0bad9f5

Please sign in to comment.