-
Notifications
You must be signed in to change notification settings - Fork 858
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
Retry on configurable exception #6991
base: main
Are you sure you want to change the base?
Changes from 4 commits
a45ebdd
9296a67
15cf507
13c3b3c
aac988d
f3d04f4
25bbf4c
a367900
596a8bd
e029f61
993385f
d91412b
20e8aaa
ef509b8
8913b52
9fb06b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,7 @@ | ||
Comparing source compatibility of opentelemetry-sdk-common-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.45.0.jar | ||
No changes. | ||
**** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.common.export.RetryPolicy (not serializable) | ||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0 | ||
+++* NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.function.Predicate<java.io.IOException> getRetryExceptionPredicate() | ||
**** MODIFIED CLASS: PUBLIC ABSTRACT STATIC io.opentelemetry.sdk.common.export.RetryPolicy$RetryPolicyBuilder (not serializable) | ||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0 | ||
+++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.export.RetryPolicy$RetryPolicyBuilder setRetryExceptionPredicate(java.util.function.Predicate<java.io.IOException>) |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -8,7 +8,9 @@ | |||||||||
import static io.opentelemetry.api.internal.Utils.checkArgument; | ||||||||||
|
||||||||||
import com.google.auto.value.AutoValue; | ||||||||||
import java.io.IOException; | ||||||||||
import java.time.Duration; | ||||||||||
import java.util.function.Predicate; | ||||||||||
|
||||||||||
/** | ||||||||||
* Configuration for exporter exponential retry policy. | ||||||||||
|
@@ -43,7 +45,8 @@ public static RetryPolicyBuilder builder() { | |||||||||
.setMaxAttempts(DEFAULT_MAX_ATTEMPTS) | ||||||||||
.setInitialBackoff(Duration.ofSeconds(DEFAULT_INITIAL_BACKOFF_SECONDS)) | ||||||||||
.setMaxBackoff(Duration.ofSeconds(DEFAULT_MAX_BACKOFF_SECONDS)) | ||||||||||
.setBackoffMultiplier(DEFAULT_BACKOFF_MULTIPLIER); | ||||||||||
.setBackoffMultiplier(DEFAULT_BACKOFF_MULTIPLIER) | ||||||||||
.setRetryExceptionPredicate((e) -> false); | ||||||||||
} | ||||||||||
|
||||||||||
/** | ||||||||||
|
@@ -66,6 +69,9 @@ public static RetryPolicyBuilder builder() { | |||||||||
/** Returns the backoff multiplier. */ | ||||||||||
public abstract double getBackoffMultiplier(); | ||||||||||
|
||||||||||
/** Returns the predicate if exception is retryable. */ | ||||||||||
public abstract Predicate<IOException> getRetryExceptionPredicate(); | ||||||||||
jack-berg marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
/** Builder for {@link RetryPolicy}. */ | ||||||||||
@AutoValue.Builder | ||||||||||
public abstract static class RetryPolicyBuilder { | ||||||||||
|
@@ -96,6 +102,13 @@ public abstract static class RetryPolicyBuilder { | |||||||||
*/ | ||||||||||
public abstract RetryPolicyBuilder setBackoffMultiplier(double backoffMultiplier); | ||||||||||
|
||||||||||
/** | ||||||||||
* Set the predicate to determine if retry should happen based on exception. No retry by | ||||||||||
* default. | ||||||||||
*/ | ||||||||||
public abstract RetryPolicyBuilder setRetryExceptionPredicate( | ||||||||||
Predicate<IOException> retryExceptionPredicate); | ||||||||||
Comment on lines
+110
to
+111
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. did you consider a customizer instead, to allow choice of either replacing or enhancing the default predicate? I realize it's not the friendliest API, but we've found the pattern really useful in AutoConfigurationCustomizer
Suggested change
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. and later use something like this
it depends how many users will want to extend it. I started the PR quickly with a thought that I need to extend rertry policy, but after some time I realized if a user wants to change the default policy it's ok just to override. but pls tell me if you think it's nice to have the enhance option for it and I will cover it in this PR and next PR. |
||||||||||
|
||||||||||
abstract RetryPolicy autoBuild(); | ||||||||||
|
||||||||||
/** Build and return a {@link RetryPolicy} with the values of this builder. */ | ||||||||||
|
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.
The OR here is interesting. It means a user can choose to expand the definition of what is retryable but not reduce it. I wonder if there are any cases when you would not want to retry when the default would retry. 🤔
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's exactly the idea
I would say no 🤔
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.
I think we might..
Suppose we want expose options to give full control to the user over what's retryable (as I alluded to in the end of this comment), we'd probably want to do something like:
setRetryPredicate(Predicate<Throwable>)
In this case, its possible that a user doesn't want to retry on a particular response status code like 502, even when the default behavior is to retry on it.
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.
I did not fully understand the idea
the current implementation allows only to extend retry conditions, but we can change it to override or extend so user will have this option and it's probably what you meant by this comment below
so we could achieve it
we probably should not mix status codes and exception in the same predicate but use two predicates separately. what do you think ? 🤔
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.
I've seen HTTP clients generate exceptions when the status code is 4xx or 5xx, and this is essentially going in that direction. All non-200 results flow flow through a
Predicate<Throwable>
, and the caller can setup different rules for differentThrowable
s. Supposing we translate non-200 responses to an exception class like our HttpExportException, example usage might look like:I suppose its not super important if exceptions and error responses are handled in a single predicate vs. two separate predicates, but I think my point here is still valid, which suggests we should give the user the ability to not retry on some IOException we normally retry by default:
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.
I am a bit confused.
Do you want to say that currently we do not retry on default retryable status codes?
so in case of 429, 502, 503, 504 we throw exception in line 91 and line 96 is never executed
opentelemetry-java/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java
Lines 90 to 110 in 5640314