Skip to content

Conversation

@daniel-sanche
Copy link
Contributor

@daniel-sanche daniel-sanche commented Feb 2, 2026

Proof of concept of the RetryInfo feature. Allows the backend to set retry backoff settings

TODO:

  • the python backoff method uses truncated backoff, but the conformance tests enforce a minimum value. This is causing one of the conformance tests to be flaky
  • Do we only need the first retry info? Or do we expect multiple?
  • Feature flags?
  • implement disable feature
  • tests

@product-auto-label product-auto-label bot added size: s Pull request size is small. api: bigtable Issues related to the googleapis/python-bigtable API. labels Feb 2, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @daniel-sanche, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a proof-of-concept for a feature that enables the client to respect RetryInfo metadata embedded within retryable exceptions. By allowing the backend to communicate specific retry backoff settings, the system gains more flexible and dynamic control over retry behavior, moving beyond static exponential backoff configurations.

Highlights

  • RetryInfo Integration: Introduced the ability to parse and utilize RetryInfo metadata from retryable exceptions, allowing backend services to specify custom retry delays.
  • Dynamic Backoff Adjustment: Modified the TrackedBackoffGenerator to include a new method, set_from_exception_info, which can override the next sleep duration based on RetryInfo provided by the server.
  • Error Tracking Enhancement: Updated the _track_retryable_error callback to inspect exception details for RetryInfo and apply any specified retry delays to the backoff generator.
Changelog
  • google/cloud/bigtable/data/_helpers.py
    • Imported RetryInfo from google.rpc.error_details_pb2 to enable handling of retry information.
    • Refactored the __next__ method in TrackedBackoffGenerator to ensure the underlying sleep generator always progresses.
    • Added a new method set_from_exception_info to TrackedBackoffGenerator for setting the next sleep time based on a RetryInfo object.
  • google/cloud/bigtable/data/_metrics/tracked_retry.py
    • Imported RetryInfo from google.rpc.error_details_pb2.
    • Modified the _track_retryable_error function to accept a TrackedBackoffGenerator instance.
    • Implemented logic within _track_retryable_error to extract RetryInfo from exception details and update the backoff generator accordingly.
    • Updated the tracked_retry function to pass the backoff_generator to the on_error callback.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a feature to respect RetryInfo metadata from retryable exceptions, allowing the backend to suggest retry backoff settings. However, a critical regression was introduced in google/cloud/bigtable/data/_metrics/tracked_retry.py where the signature of _track_retryable_error was changed without updating its call site in _track_terminal_error, leading to a TypeError when a timeout occurs. Additionally, I've provided suggestions to improve logging for debuggability and optimize a list comprehension for better performance and style.


def _track_retryable_error(
operation: ActiveOperationMetric,
backoff_generator: TrackedBackoffGenerator,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The function _track_retryable_error has been updated to require a mandatory backoff_generator argument. However, the call site on line 118 (within _track_terminal_error) was not updated to provide this argument. This will lead to a TypeError and an application crash whenever a timeout occurs during an active retry attempt. Please ensure all call sites are updated to provide the required argument (e.g., _track_retryable_error(operation, operation.backoff_generator)(attempt_exc)).

Comment on lines 69 to 71
info_matches = [field for field in exc.details if isinstance(field, RetryInfo)]
if info_matches:
backoff_generator.set_from_exception_info(info_matches[0])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The list comprehension [field for ...] builds a full list of all RetryInfo objects found in exc.details, even though only the first one is used. For efficiency, especially if exc.details could be large, it's better to use a generator expression with next() to find only the first match without iterating over the entire list unnecessarily.

Suggested change
info_matches = [field for field in exc.details if isinstance(field, RetryInfo)]
if info_matches:
backoff_generator.set_from_exception_info(info_matches[0])
first_info = next((field for field in exc.details if isinstance(field, RetryInfo)), None)
if first_info:
backoff_generator.set_from_exception_info(first_info)

@daniel-sanche daniel-sanche changed the title [DRAFT] feat: respect RetryInfo metadata from retryable exceptions [DRAFT] feat: use RetryInfo metadata from retryable exceptions Feb 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: bigtable Issues related to the googleapis/python-bigtable API. size: s Pull request size is small.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant