-
Notifications
You must be signed in to change notification settings - Fork 927
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
Add builder for Backoff #5488
base: main
Are you sure you want to change the base?
Add builder for Backoff #5488
Changes from 9 commits
6ed81ab
84584c8
2529af3
8e539f8
315d7fe
7575359
a08db2f
5517044
343cbca
630f1d1
a3b2364
df68b82
c9af5b6
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 |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* Copyright 2024 LY Corporation | ||
* | ||
* LY Corporation licenses this file to you under the Apache License, | ||
* version 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at: | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package com.linecorp.armeria.client.retry; | ||
|
||
import static com.google.common.base.Preconditions.checkArgument; | ||
|
||
import com.linecorp.armeria.common.annotation.UnstableApi; | ||
|
||
/** | ||
* A builder for creating instances of {@link ExponentialBackoff}. | ||
* | ||
* <p>This builder allows you to configure an exponential backoff strategy by specifying | ||
* the initial delay, the maximum delay, and a multiplier. The exponential backoff | ||
* increases the delay between retries exponentially, starting from the initial delay and | ||
* multiplying the delay by the specified multiplier after each retry, up to the maximum delay.</p> | ||
* | ||
* <p>Example usage:</p> | ||
* | ||
* <pre> | ||
* {@code | ||
* ExponentialBackoff backoff = new ExponentialBackoffBuilder() | ||
* .initialDelayMillis(100) | ||
* .maxDelayMillis(10000) | ||
* .multiplier(2.0) | ||
* .build(); | ||
* } | ||
* </pre> | ||
* | ||
* @see ExponentialBackoff | ||
*/ | ||
@UnstableApi | ||
public final class ExponentialBackoffBuilder { | ||
private long initialDelayMillis; | ||
private long maxDelayMillis; | ||
private double multiplier = 2.0; | ||
|
||
ExponentialBackoffBuilder() {} | ||
|
||
ikhoon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* Builds and returns a new {@link ExponentialBackoff} instance with the configured | ||
* initial delay, maximum delay, and multiplier. | ||
* | ||
* @return a newly created {@link ExponentialBackoff} with the configured delays and multiplier | ||
*/ | ||
public Backoff build() { | ||
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. Code style) We conventionally place |
||
return new ExponentialBackoff(initialDelayMillis, maxDelayMillis, multiplier); | ||
} | ||
|
||
/** | ||
* Sets the initial delay in milliseconds for the {@link ExponentialBackoff}. | ||
* | ||
* <p>The initial delay is the starting value for the exponential backoff, determining | ||
* the delay before the first retry. Subsequent delays will increase exponentially | ||
* based on the multiplier.</p> | ||
* | ||
* @param initialDelayMillis the initial delay in milliseconds | ||
* @return this {@code ExponentialBackoffBuilder} instance for method chaining | ||
*/ | ||
public ExponentialBackoffBuilder initialDelayMillis(long initialDelayMillis) { | ||
checkArgument(initialDelayMillis >= 0, "initialDelayMillis: %s (expected: >= 0)", initialDelayMillis); | ||
this.initialDelayMillis = initialDelayMillis; | ||
ikhoon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return this; | ||
} | ||
|
||
/** | ||
* Sets the maximum delay in milliseconds for the {@link ExponentialBackoff}. | ||
* | ||
* <p>The maximum delay is the upper limit for the backoff delay. Once the delay reaches | ||
* this value, it will not increase further, even if the multiplier would result in a higher value.</p> | ||
* | ||
* @param maxDelayMillis the maximum delay in milliseconds | ||
* @return this {@code ExponentialBackoffBuilder} instance for method chaining | ||
*/ | ||
public ExponentialBackoffBuilder maxDelayMillis(long maxDelayMillis) { | ||
checkArgument(maxDelayMillis >= 0, "maxDelayMillis: %s (expected: >= 0)", maxDelayMillis); | ||
this.maxDelayMillis = maxDelayMillis; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the multiplier for the {@link ExponentialBackoff}. | ||
* | ||
* <p>The multiplier controls how much the delay increases after each retry. | ||
* The delay for each retry is determined by multiplying the previous delay by this value, | ||
* until the maximum delay is reached.</p> | ||
* | ||
* @param multiplier the multiplier for the exponential backoff | ||
* @return this {@code ExponentialBackoffBuilder} instance for method chaining | ||
*/ | ||
public ExponentialBackoffBuilder multiplier(double multiplier) { | ||
checkArgument(multiplier > 1.0, "multiplier: %s (expected: > 1.0)", multiplier); | ||
this.multiplier = multiplier; | ||
return this; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,92 @@ | ||||||
/* | ||||||
* Copyright 2024 LY Corporation | ||||||
* | ||||||
* LY Corporation licenses this file to you under the Apache License, | ||||||
* version 2.0 (the "License"); you may not use this file except in compliance | ||||||
* with the License. You may obtain a copy of the License at: | ||||||
* | ||||||
* https://www.apache.org/licenses/LICENSE-2.0 | ||||||
* | ||||||
* Unless required by applicable law or agreed to in writing, software | ||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||||
* License for the specific language governing permissions and limitations | ||||||
* under the License. | ||||||
*/ | ||||||
package com.linecorp.armeria.client.retry; | ||||||
|
||||||
import static com.google.common.base.Preconditions.checkArgument; | ||||||
|
||||||
import com.linecorp.armeria.common.annotation.UnstableApi; | ||||||
|
||||||
/** | ||||||
* A builder for creating instances of {@link FibonacciBackoff}. | ||||||
* | ||||||
* <p>This builder allows you to configure a Fibonacci backoff strategy by specifying | ||||||
* an initial delay and a maximum delay in milliseconds. The Fibonacci backoff strategy | ||||||
* increases the delay between retries according to the Fibonacci sequence, while respecting | ||||||
* the configured maximum delay.</p> | ||||||
* | ||||||
* <p>Example usage:</p> | ||||||
* | ||||||
* <pre> | ||||||
* {@code | ||||||
* FibonacciBackoff backoff = new FibonacciBackoffBuilder() | ||||||
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. Ditto. Please use builder methods. |
||||||
* .initialDelayMillis(100) | ||||||
* .maxDelayMillis(10000) | ||||||
* .build(); | ||||||
* } | ||||||
* </pre> | ||||||
* | ||||||
* @see FibonacciBackoff | ||||||
*/ | ||||||
@UnstableApi | ||||||
public final class FibonacciBackoffBuilder { | ||||||
private long initialDelayMillis; | ||||||
private long maxDelayMillis; | ||||||
|
||||||
FibonacciBackoffBuilder() {} | ||||||
|
||||||
/** | ||||||
* Builds and returns a new {@link FibonacciBackoff} instance with the configured | ||||||
* initial and maximum delays. | ||||||
* | ||||||
* @return a newly created {@link FibonacciBackoff} with the configured delays | ||||||
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. It seems redundant.
Suggested change
|
||||||
*/ | ||||||
public Backoff build() { | ||||||
return new FibonacciBackoff(initialDelayMillis, maxDelayMillis); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Sets the initial delay in milliseconds for the {@link FibonacciBackoff}. | ||||||
* | ||||||
* <p>The initial delay is the base value from which the Fibonacci sequence will start, | ||||||
* and it determines the delay before the first retry.</p> | ||||||
* | ||||||
* @param initialDelayMillis the initial delay in milliseconds | ||||||
* @return this {@code FibonacciBackoffBuilder} instance for method chaining | ||||||
*/ | ||||||
public FibonacciBackoffBuilder initialDelayMillis(long initialDelayMillis) { | ||||||
checkArgument(initialDelayMillis >= 0, | ||||||
"initialDelayMillis: %s (expected: >= 0)", initialDelayMillis); | ||||||
|
||||||
this.initialDelayMillis = initialDelayMillis; | ||||||
return this; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Sets the maximum delay in milliseconds for the {@link FibonacciBackoff}. | ||||||
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.
Suggested change
|
||||||
* | ||||||
* <p>The maximum delay sets an upper limit to the delays generated by the Fibonacci | ||||||
* sequence. Once the delays reach this value, they will not increase further.</p> | ||||||
* | ||||||
* @param maxDelayMillis the maximum delay in milliseconds | ||||||
* @return this {@code FibonacciBackoffBuilder} instance for method chaining | ||||||
*/ | ||||||
public FibonacciBackoffBuilder maxDelayMillis(long maxDelayMillis) { | ||||||
checkArgument(maxDelayMillis >= 0, | ||||||
"maxDelayMillis: %s (expected: >= 0)", maxDelayMillis); | ||||||
this.maxDelayMillis = maxDelayMillis; | ||||||
return this; | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,70 @@ | ||||||
/* | ||||||
* Copyright 2024 LY Corporation | ||||||
* | ||||||
* LY Corporation licenses this file to you under the Apache License, | ||||||
* version 2.0 (the "License"); you may not use this file except in compliance | ||||||
* with the License. You may obtain a copy of the License at: | ||||||
* | ||||||
* https://www.apache.org/licenses/LICENSE-2.0 | ||||||
* | ||||||
* Unless required by applicable law or agreed to in writing, software | ||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||||
* License for the specific language governing permissions and limitations | ||||||
* under the License. | ||||||
*/ | ||||||
package com.linecorp.armeria.client.retry; | ||||||
|
||||||
import static com.google.common.base.Preconditions.checkArgument; | ||||||
|
||||||
import com.linecorp.armeria.common.annotation.UnstableApi; | ||||||
|
||||||
/** | ||||||
* A builder for creating instances of {@link FixedBackoff}. | ||||||
* | ||||||
* <p>This builder allows you to configure the delay duration for a fixed backoff strategy. | ||||||
* You can specify the delay in milliseconds and then create a {@link FixedBackoff} instance | ||||||
* with the configured delay.</p> | ||||||
* | ||||||
* <p>Example usage:</p> | ||||||
* | ||||||
* <pre> | ||||||
* {@code | ||||||
* FixedBackoff backoff = new FixedBackoffBuilder() | ||||||
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. The constructor of
Suggested change
|
||||||
* .delayMillis(1000) | ||||||
* .build(); | ||||||
* } | ||||||
* </pre> | ||||||
* | ||||||
* @see FixedBackoff | ||||||
*/ | ||||||
@UnstableApi | ||||||
public final class FixedBackoffBuilder { | ||||||
private long delayMillis; | ||||||
|
||||||
FixedBackoffBuilder() {} | ||||||
|
||||||
/** | ||||||
* Builds and returns a new {@link FixedBackoff} instance with the configured delay. | ||||||
* | ||||||
* @return a newly created {@link FixedBackoff} with the configured delay | ||||||
*/ | ||||||
public Backoff build() { | ||||||
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. Ditto. Please move to the bottom of this class. |
||||||
return new FixedBackoff(delayMillis); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Sets the delay duration in milliseconds for the {@link FixedBackoff}. | ||||||
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.
Suggested change
|
||||||
* | ||||||
* <p>This value determines the fixed amount of time the backoff will delay | ||||||
* before retrying an operation.</p> | ||||||
* | ||||||
* @param delayMillis the delay in milliseconds | ||||||
* @return this {@code FixedBackoffBuilder} instance for method chaining | ||||||
*/ | ||||||
public FixedBackoffBuilder delayMillis(long delayMillis) { | ||||||
checkArgument(delayMillis >= 0, "delayMillis: %s (expected: >= 0)", delayMillis); | ||||||
this.delayMillis = delayMillis; | ||||||
return this; | ||||||
} | ||||||
} |
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 would be worth allowing to configure jitter and max attempts in all builder methods.
What do you think of introducing
AbstractBackoffBuilder
to set them?