Skip to content

Commit

Permalink
Adaptive bulkhead 2023.1.4 (resilience4j#1873)
Browse files Browse the repository at this point in the history
* Super early draft of adaptive bulkhead.
!!! NOT TESTED !!!

* Small proof of concept test.

* Code cleanup. Builder for BulkheadAdaptationConfig

* Small code clean up. Metrics implementation. Additional TODOs

* Additional TODOs

* Small renaming

* first round of adaptive bulkhead updates

* first round of adaptive bulkhead updates

* first round of adaptive bulkhead updates

* second round of adaptive bulkhead updates

* Sonar fixes

* adaptive bulkhead refactoring to match last discussion

* adaptive bulkhead refactoring to match last discussion

* adaptive bulkhead refactoring to match last discussion

* adaptive bulkhead refactoring to match last discussion

* adaptive bulkhead refactoring to match last discussion

* adaptive bulkhead refactoring to match last discussion

* Sonar fixes

* reduce code duplication

* add exception predicate unit testing

* first round of updates after introducing sliding window with AIMD limiter

* Sonar fixes

* Sonar fixes

* first round of updates for making adaptive policy independent from bulkhead

* first round of applying the review comments

* first round of applying the review comments

* second round of applying the review comments

* Third round of applying the review comments

* fix javadoc

* sonar fixes

* review comments round 4

* code cleanup

* review comments round 5

* review comments round 5

* review comments round 5

* #review comments

* Sonar fixes

* increase test coverage

* first round of review comments apply

* first round of review comments apply

* fix compile issue

* tune the adaptive bulkhead test

* New Draft

* Adaptive Bulkhead Draft

* Adaptive Bulkhead 2 Draft (resilience4j#1306)

* Remove AIMD leftovers (resilience4j#1397)

* Issue#651: Support to exclude MetricsAutoConfiguration

* Propagate clock into CircuitBreakerMetrics to allow mocked time-based tests. (resilience4j#844)

* Issue resilience4j#596: The Spring Boot fallback method is not invoked when a BulkheadFullException occurs resilience4j#847

The ThreadPoolBulkhead is does not return a CompletionStage when a task could not be submitted, because the Bulkhead is full. The ThreadPoolBulkhead throws a BulkheadFullException instead. Analog to the ThreadPoolExecutor which throws the RejectedExecutionException. The BulkheadFullException is not handled correctly by the BulkheadAspect.
The BulkheadAspect should convert the BulkheadFullException into a exceptionally completed future so that the FallbackDecorator works as expected.

* Added timelimiter support for resilience4j-ratpack (resilience4j#865)

* Sonar critical issues solved: (resilience4j#876)

* Remove usage of generic wildcard type.
* Define a constant instead of duplicating this literal
* Refactor this method to reduce its Cognitive Complexity
* Add a nested comment explaining why this method is empty
* Class names should not shadow interfaces or superclasses
Warnings removed.

* Updated Gradle, Migrated from Bintray to Sonatype, migrated to GitHub Actions

Co-authored-by: Robert Winkler <rwinkler@telekom.de>

* Fixed sonar smells

* Small proof of concept test.

* first round of adaptive bulkhead updates

* second round of adaptive bulkhead updates

* Sonar fixes

* first round of applying the review comments

* Sonar fixes

* first round of review comments apply

* tune the adaptive bulkhead test

* New Draft

* Adaptive Bulkhead 2 Draft (resilience4j#1306)

* Remove AIMD leftovers (resilience4j#1397)

* updated to master

---------

Co-authored-by: bstorozhuk <storozhuk.b.m@gmail.com>
Co-authored-by: Mahmoud Romeh <mahmoud.romeh@collibra.com>
Co-authored-by: Robert Winkler <rwinkler@telekom.de>
Co-authored-by: KrnSaurabh <39181662+KrnSaurabh@users.noreply.github.com>
Co-authored-by: Robert Winkler <robwin@t-online.de>
Co-authored-by: Dan Maas <daniel.maas@target.com>
  • Loading branch information
7 people authored and Tomasz Skowroński committed Jan 5, 2024
1 parent 7588101 commit 976f478
Show file tree
Hide file tree
Showing 46 changed files with 4,425 additions and 57 deletions.
1 change: 1 addition & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ allprojects {

version = '2.3.0-SNAPSHOT'
group = 'io.github.resilience4j'
description = 'Resilience4j is a lightweight, easy-to-use fault tolerance library designed for Java8 and functional programming'
description = 'Resilience4j is a lightweight, easy-to-use fault tolerance library designed for Java17+ and functional programming'

repositories {
mavenCentral()
Expand Down
1 change: 1 addition & 0 deletions resilience4j-bulkhead/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dependencies {
api project(':resilience4j-core')
testImplementation project(':resilience4j-test')
testImplementation 'org.knowm.xchart:xchart:3.8.3'
}
ext.moduleName = 'io.github.resilience4j.bulkhead'
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@
*/
package io.github.resilience4j.bulkhead;

import io.github.resilience4j.bulkhead.adaptive.AdaptiveBulkhead;

/**
* A {@link BulkheadFullException} signals that the bulkhead is full.
*/
public class BulkheadFullException extends RuntimeException {

private static final String ERROR_FURTHER_CALLS = "Bulkhead '%s' is full and does not permit further calls";
private static final String ERROR_PERMISSION_WAIT = "Bulkhead '%s' is full and thread was interrupted during permission wait";

private BulkheadFullException(String message, boolean writableStackTrace) {
super(message, null, false, writableStackTrace);
}
Expand All @@ -33,17 +38,14 @@ private BulkheadFullException(String message, boolean writableStackTrace) {
* @param bulkhead the Bulkhead.
*/
public static BulkheadFullException createBulkheadFullException(Bulkhead bulkhead) {
boolean writableStackTraceEnabled = bulkhead.getBulkheadConfig()
boolean writableStackTraceEnabled = bulkhead.getBulkheadConfig()
.isWritableStackTraceEnabled();

String message;
if (Thread.currentThread().isInterrupted()) {
message = String
.format("Bulkhead '%s' is full and thread was interrupted during permission wait",
bulkhead.getName());
message = String.format(ERROR_PERMISSION_WAIT, bulkhead.getName());
} else {
message = String.format("Bulkhead '%s' is full and does not permit further calls",
bulkhead.getName());
message = String.format(ERROR_FURTHER_CALLS, bulkhead.getName());
}

return new BulkheadFullException(message, writableStackTraceEnabled);
Expand All @@ -58,8 +60,28 @@ public static BulkheadFullException createBulkheadFullException(ThreadPoolBulkhe
boolean writableStackTraceEnabled = bulkhead.getBulkheadConfig()
.isWritableStackTraceEnabled();

String message = String
.format("Bulkhead '%s' is full and does not permit further calls", bulkhead.getName());
String message = String.format(ERROR_FURTHER_CALLS, bulkhead.getName());

return new BulkheadFullException(message, writableStackTraceEnabled);
}
/**
* The constructor with a message.
*
* @param bulkhead the AdaptiveLimitBulkhead.
*/
public BulkheadFullException(AdaptiveBulkhead bulkhead) {
super(String.format(ERROR_FURTHER_CALLS, bulkhead.getName()));
}

/**
* The constructor with a message.
*
* @param bulkhead the AdaptiveBulkheadStateMachine.
*/
public static BulkheadFullException createBulkheadFullException(AdaptiveBulkhead bulkhead) {
boolean writableStackTraceEnabled = bulkhead.getBulkheadConfig().isWritableStackTraceEnabled();

String message = String.format(ERROR_FURTHER_CALLS, bulkhead.getName());

return new BulkheadFullException(message, writableStackTraceEnabled);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,21 +186,6 @@ static ThreadPoolBulkhead of(String name,
*/
ThreadPoolBulkheadEventPublisher getEventPublisher();

/**
* Returns a supplier which submits a value-returning task for execution and
* returns a CompletionStage representing the asynchronous computation of the task.
*
* The Supplier throws a {@link BulkheadFullException} if the task cannot be submitted, because the Bulkhead is full.
*
* @param supplier the value-returning task to submit
* @param <T> the result type of the callable
* @return a supplier which submits a value-returning task for execution and returns a CompletionStage representing
* the asynchronous computation of the task
*/
default <T> Supplier<CompletionStage<T>> decorateSupplier(Supplier<T> supplier) {
return decorateSupplier(this, supplier);
}

/**
* Returns a supplier which submits a value-returning task for execution and
* returns a CompletionStage representing the asynchronous computation of the task.
Expand Down
Loading

0 comments on commit 976f478

Please sign in to comment.