-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Implement failure circuit breaker #18359
Closed
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
de3362b
feat: Implement failure circuit breaker
amishra-u e32984a
add missing files
amishra-u 60c71b6
incorporate feedback
amishra-u 9be3204
remove final keyword
amishra-u f949204
Merge branch 'bazelbuild:master' into master
amishra-u 00a317c
Remove parameterized test
amishra-u 038ec0b
add missed test
amishra-u File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -252,4 +252,8 @@ public void close() { | |
} | ||
channel.release(); | ||
} | ||
|
||
RemoteRetrier getRetrier() { | ||
return this.retrier; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
src/main/java/com/google/devtools/build/lib/remote/circuitbreaker/BUILD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
load("@rules_java//java:defs.bzl", "java_library") | ||
|
||
package( | ||
default_applicable_licenses = ["//:license"], | ||
default_visibility = ["//src:__subpackages__"], | ||
) | ||
|
||
filegroup( | ||
name = "srcs", | ||
srcs = glob(["*"]), | ||
visibility = ["//src:__subpackages__"], | ||
) | ||
|
||
java_library( | ||
name = "circuitbreaker", | ||
srcs = glob(["*.java"]), | ||
deps = [ | ||
"//src/main/java/com/google/devtools/build/lib/remote:Retrier", | ||
"//src/main/java/com/google/devtools/build/lib/remote/common:cache_not_found_exception", | ||
"//src/main/java/com/google/devtools/build/lib/remote/options", | ||
"//third_party:guava", | ||
] | ||
) |
33 changes: 33 additions & 0 deletions
33
src/main/java/com/google/devtools/build/lib/remote/circuitbreaker/CircuitBreakerFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.google.devtools.build.lib.remote.circuitbreaker; | ||
|
||
import com.google.devtools.build.lib.remote.Retrier; | ||
import com.google.common.collect.ImmutableSet; | ||
import com.google.devtools.build.lib.remote.common.CacheNotFoundException; | ||
import com.google.devtools.build.lib.remote.options.RemoteOptions; | ||
|
||
/** | ||
* Factory for {@link Retrier.CircuitBreaker} | ||
*/ | ||
public class CircuitBreakerFactory { | ||
|
||
public static final ImmutableSet<Class<? extends Exception>> DEFAULT_IGNORED_ERRORS = | ||
ImmutableSet.of(CacheNotFoundException.class); | ||
|
||
private CircuitBreakerFactory() { | ||
} | ||
|
||
/** | ||
* Creates the instance of the {@link Retrier.CircuitBreaker} as per the strategy defined in {@link RemoteOptions}. | ||
* In case of undefined strategy defaults to {@link Retrier.ALLOW_ALL_CALLS} implementation. | ||
* | ||
* @param remoteOptions The configuration for the CircuitBreaker implementation. | ||
* @return an instance of CircuitBreaker. | ||
*/ | ||
public static Retrier.CircuitBreaker createCircuitBreaker(final RemoteOptions remoteOptions) { | ||
if (remoteOptions.circuitBreakerStrategy == RemoteOptions.CircuitBreakerStrategy.FAILURE) { | ||
return new FailureCircuitBreaker(remoteOptions.remoteFailureThreshold, | ||
(int) remoteOptions.remoteFailureWindowInterval.toMillis()); | ||
} | ||
return Retrier.ALLOW_ALL_CALLS; | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
src/main/java/com/google/devtools/build/lib/remote/circuitbreaker/FailureCircuitBreaker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.google.devtools.build.lib.remote.circuitbreaker; | ||
|
||
import com.google.common.collect.ImmutableSet; | ||
import com.google.devtools.build.lib.remote.Retrier; | ||
|
||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.ScheduledExecutorService; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
/** | ||
* The {@link FailureCircuitBreaker} implementation of the {@link Retrier.CircuitBreaker} prevents further calls to a remote cache | ||
* once the number of failures within a given window exceeds a specified threshold for a build. | ||
* In the context of Bazel, a new instance of {@link Retrier.CircuitBreaker} is created for each build. Therefore, if the circuit | ||
* breaker trips during a build, the remote cache will be disabled for that build. However, it will be enabled again | ||
* for the next build as a new instance of {@link Retrier.CircuitBreaker} will be created. | ||
*/ | ||
public class FailureCircuitBreaker implements Retrier.CircuitBreaker { | ||
|
||
private State state; | ||
private final AtomicInteger failures; | ||
private final int failureThreshold; | ||
private final int slidingWindowSize; | ||
private final ScheduledExecutorService scheduledExecutor; | ||
private final ImmutableSet<Class<? extends Exception>> ignoredErrors; | ||
|
||
/** | ||
* Creates a {@link FailureCircuitBreaker}. | ||
* | ||
* @param failureThreshold is used to set the number of failures required to trip the circuit breaker in given | ||
* time window. | ||
* @param slidingWindowSize the size of the sliding window in milliseconds to calculate the number of failures. | ||
*/ | ||
public FailureCircuitBreaker(int failureThreshold, int slidingWindowSize) { | ||
this.failureThreshold = failureThreshold; | ||
this.failures = new AtomicInteger(0); | ||
this.slidingWindowSize = slidingWindowSize; | ||
this.state = State.ACCEPT_CALLS; | ||
this.scheduledExecutor = slidingWindowSize > 0 ? Executors.newSingleThreadScheduledExecutor() : null; | ||
this.ignoredErrors = CircuitBreakerFactory.DEFAULT_IGNORED_ERRORS; | ||
} | ||
|
||
@Override | ||
public State state() { | ||
return this.state; | ||
} | ||
|
||
@Override | ||
public void recordFailure(Exception e) { | ||
if (!ignoredErrors.contains(e.getClass())) { | ||
int failureCount = failures.incrementAndGet(); | ||
if (slidingWindowSize > 0) { | ||
scheduledExecutor.schedule(failures::decrementAndGet, slidingWindowSize, TimeUnit.MILLISECONDS); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a comment maybe? Why |
||
} | ||
// Since the state can only be changed to the open state, synchronization is not required. | ||
if (failureCount > this.failureThreshold) { | ||
this.state = State.REJECT_CALLS; | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void recordSuccess() { | ||
// do nothing, implement if we need to set threshold on failure rate instead of count. | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this needed at all? I don't see this gets used anywhere or in the initerface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is used test methods inside RemoteModuleTest class.