- Notifications
You must be signed in to change notification settings - Fork90
feat: support dynamic retry backoff values#793
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Merged
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes fromall commits
Commits
Show all changes
12 commits Select commitHold shift + click to select a range
e0c1b45
feat: retry generates backoff value after completing on_error callbacks
daniel-sanche240fed0
added comment
daniel-sanche6710fcb
use single sleep iterator for retries
daniel-sanched99844a
fix tests
daniel-sanche465e023
update variable name
daniel-sanche7e7c078
adjusted docstring
daniel-sanche7498f2b
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot]374f17e
fixed mypy issues
daniel-sanche7a00b52
Merge branch 'main' into postpone_sleep_generation
daniel-sanche58334f7
Merge branch 'main' into postpone_sleep_generation
partheaeb74572
added comment
daniel-sanchee9940f3
added unit tests for dynamic backoff
daniel-sancheFile filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
---|---|---|
@@ -25,7 +25,7 @@ | ||
import time | ||
from enum import Enum | ||
from typing import Any, Callable, Optional,Iterator,TYPE_CHECKING | ||
import requests.exceptions | ||
@@ -174,7 +174,7 @@ def build_retry_error( | ||
def _retry_error_helper( | ||
exc: Exception, | ||
deadline: float | None, | ||
sleep_iterator: Iterator[float], | ||
error_list: list[Exception], | ||
predicate_fn: Callable[[Exception], bool], | ||
on_error_fn: Callable[[Exception], None] | None, | ||
@@ -183,7 +183,7 @@ def _retry_error_helper( | ||
tuple[Exception, Exception | None], | ||
], | ||
original_timeout: float | None, | ||
) -> float: | ||
""" | ||
Shared logic for handling an error for all retry implementations | ||
@@ -194,13 +194,15 @@ def _retry_error_helper( | ||
Args: | ||
- exc: the exception that was raised | ||
- deadline: the deadline for the retry, calculated as a diff from time.monotonic() | ||
-sleep_iterator: iterator to drawthe nextbackoff value from | ||
- error_list: the list of exceptions that have been raised so far | ||
- predicate_fn: takes `exc` and returns true if the operation should be retried | ||
- on_error_fn: callback to execute when a retryable error occurs | ||
- exc_factory_fn: callback used to build the exception to be raised on terminal failure | ||
- original_timeout_val: the original timeout value for the retry (in seconds), | ||
to be passed to the exception factory for building an error message | ||
Returns: | ||
- the sleep value chosen before the next attempt | ||
""" | ||
error_list.append(exc) | ||
if not predicate_fn(exc): | ||
@@ -212,6 +214,12 @@ def _retry_error_helper( | ||
raise final_exc from source_exc | ||
if on_error_fn is not None: | ||
on_error_fn(exc) | ||
# next_sleep is fetched after the on_error callback, to allow clients | ||
# to update sleep_iterator values dynamically in response to errors | ||
try: | ||
next_sleep = next(sleep_iterator) | ||
parthea marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
except StopIteration: | ||
raise ValueError("Sleep generator stopped yielding sleep values.") from exc | ||
if deadline is not None and time.monotonic() + next_sleep > deadline: | ||
final_exc, source_exc = exc_factory_fn( | ||
error_list, | ||
@@ -222,6 +230,7 @@ def _retry_error_helper( | ||
_LOGGER.debug( | ||
"Retrying due to {}, sleeping {:.1f}s ...".format(error_list[-1], next_sleep) | ||
) | ||
return next_sleep | ||
class _BaseRetry(object): | ||
This file contains hidden or 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 |
---|---|---|
@@ -107,8 +107,11 @@ def retry_target_stream( | ||
time.monotonic() + timeout if timeout is not None else None | ||
) | ||
error_list: list[Exception] = [] | ||
sleep_iter = iter(sleep_generator) | ||
# continue trying until an attempt completes, or a terminal exception is raised in _retry_error_helper | ||
# TODO: support max_attempts argument: https://github.com/googleapis/python-api-core/issues/535 | ||
while True: | ||
parthea marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
# Start a new retry loop | ||
try: | ||
# Note: in the future, we can add a ResumptionStrategy object | ||
@@ -121,20 +124,18 @@ def retry_target_stream( | ||
# This function explicitly must deal with broad exceptions. | ||
except Exception as exc: | ||
# defer to shared logic for handling errors | ||
next_sleep =_retry_error_helper( | ||
exc, | ||
deadline, | ||
sleep_iter, | ||
error_list, | ||
predicate, | ||
on_error, | ||
exception_factory, | ||
timeout, | ||
) | ||
# if exception not raised, sleep before next attempt | ||
time.sleep(next_sleep) | ||
class StreamingRetry(_BaseRetry): | ||
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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.
Uh oh!
There was an error while loading.Please reload this page.
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.