This repository was archived by the owner on Apr 1, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 65
feat: Added rst_stream exception handling for ReadRows. #1298
Merged
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
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 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,13 +16,14 @@ | |
| """ | ||
| from __future__ import annotations | ||
|
|
||
| from typing import Sequence, List, Tuple, TYPE_CHECKING, Union | ||
| from typing import Callable, Sequence, List, Tuple, TYPE_CHECKING, Union | ||
| import time | ||
| import enum | ||
| from collections import namedtuple | ||
| from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery | ||
|
|
||
| from google.api_core import exceptions as core_exceptions | ||
| from google.api_core import retry as retries | ||
| from google.api_core.retry import RetryFailureReason | ||
| from google.cloud.bigtable.data.exceptions import RetryExceptionGroup | ||
|
|
||
|
|
@@ -47,6 +48,15 @@ | |
| # used by every data client as a default project name for testing on Bigtable emulator. | ||
| _DEFAULT_BIGTABLE_EMULATOR_CLIENT = "google-cloud-bigtable-emulator" | ||
|
|
||
| # Internal error messages that can be retried during ReadRows. Internal error messages with this error | ||
| # text should be treated as Unavailable error messages with the same error text, and will therefore be | ||
| # treated as Unavailable errors rather than Internal errors. | ||
| _RETRYABLE_INTERNAL_ERROR_MESSAGES = ( | ||
| "rst_stream", | ||
| "rst stream", | ||
| "received unexpected eos on data frame from server", | ||
| ) | ||
|
|
||
| # used to identify an active bigtable resource that needs to be warmed through PingAndWarm | ||
| # each instance/app_profile_id pair needs to be individually tracked | ||
| _WarmedInstanceKey = namedtuple( | ||
|
|
@@ -122,6 +132,33 @@ def _retry_exception_factory( | |
| return source_exc, cause_exc | ||
|
|
||
|
|
||
| def _read_rows_predicate_with_exceptions(*exception_types: type[Exception]) -> Callable[[Exception], bool]: | ||
| """A custom retry predicate for ReadRows. | ||
|
|
||
| This predicate treats Internal error messages with RST_STREAM errors as | ||
| ServiceUnavailable errors and will retry them if the Unavailable exception is retryable. | ||
|
|
||
| Args: | ||
| exception_types: Exception types to be retried during operation | ||
|
|
||
| Returns: | ||
| Callable[[Exception], bool]: A retry predicate that takes in an exception and | ||
| returns whether or not that exception is retryable | ||
| """ | ||
| is_exception_type = retries.if_exception_type(*exception_types) | ||
|
|
||
| def predicate(exception: Exception) -> bool: | ||
| return (isinstance(exception, core_exceptions.InternalServerError) and any(m in exception.message.lower() for m in _RETRYABLE_INTERNAL_ERROR_MESSAGES)) or is_exception_type(exception) | ||
|
|
||
| # Treating RST_STREAM internal errors as unavailable errors is only done if ServiceUnavailable is one of the | ||
| # given exception types. If InternalServerError is also a retryable exception, we don't necessarily need the | ||
| # custom predicate either. | ||
| if core_exceptions.ServiceUnavailable in exception_types and core_exceptions.InternalServerError not in exception_types: | ||
| return predicate | ||
|
|
||
| return is_exception_type | ||
|
Contributor
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. I find the logic a bit hard to follow, with the multiple predicate functions being passed around. Can we do something like this, to put all the cases in one place? or even this? |
||
|
|
||
|
|
||
| def _get_timeouts( | ||
| operation: float | TABLE_DEFAULT, | ||
| attempt: float | None | TABLE_DEFAULT, | ||
|
|
||
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.
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.
can we call this something more specific, since it's not really tied to read_rows? Maybe _rst_stream_aware_predicate?