Skip to content

feat(bigtable): Reroute Mutations Batcher to use data client - #18200

Open
daniel-sanche wants to merge 9 commits into
shim/12-batcher-callbackfrom
shim/13-mutations-batcher
Open

daniel-sanche wants to merge 9 commits into
shim/12-batcher-callbackfrom
shim/13-mutations-batcher

Conversation

@daniel-sanche

@daniel-sanche daniel-sanche commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Migrating over @gkevinzheng PR from bigtable monorepo googleapis/python-bigtable#1309

Original description:

Changes Made:

  • Replaced mutations batcher implementation with one based off of the data client.
  • Reworked unit tests.
  • Added additional system tests.

Additional Changes:

  • 785f138: fix references in propertoes to point to data client
  • ac62f4c: removed deprecation language around flush_interval, since it is supported in the data client

Note to reviewers: This PR has already been reviewed and merged to a staging branch, with the intention of doing a single merge to main. We are now planning to slowly rollout these changes back to the main branch. Minimal re-review should be necessary

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

Copy link
Copy Markdown
Contributor

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 refactors the MutationsBatcher to delegate batching, queueing, and flow control to the underlying table implementation, removing redundant internal classes. It also updates the exception handling across both sync and async batchers to ensure that MutationsExceptionGroup only contains FailedMutationEntryError instances. A review comment points out a potential issue where unpacking error.__cause__ could result in None being added to the exceptions queue, and suggests a defensive fallback to the error itself.

Comment thread packages/google-cloud-bigtable/google/cloud/bigtable/batcher.py Outdated
@daniel-sanche
daniel-sanche force-pushed the shim/13-mutations-batcher branch from dbfc051 to 57774e9 Compare September 2, 2026 18:42
exceptions.extend(
[
FailedMutationEntryError(
failed_idx=None, failed_mutation_entry=entry, cause=e

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what does field_index=None mean? should it be the index of the current entry?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

index doesn't make as much sense for the user in the batcher context, because the user adds mutations one at a time, and has no context into what the underlying batch looks like. The batcher strips out the indexes for this reason.

)
return status_pb2.Status(
code=code_pb2.Code.UNKNOWN,
message="An unknown error has occurred",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maybe change this to GoogleApiCAllError with Unknown status code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

# FailedMutationEntryError always has an Exception cause;
# defensively fall back to error itself if __cause__ is None.
cause = error.__cause__ if error.__cause__ is not None else error
self._exceptions.put(cause)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could there be other types of error? we should put them in the exception list

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We don't expect there to be, but we can add a guard to be safe


return responses
self._close_batcher()
self._init_batcher()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is it expensive to keep close and reopen batcher? would it be better if the data client batcher expose a flush method?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I believe the original plan was to implement flush, but Igor and Kevin had a discussion, and decided to just do this instead. Maybe we can find a record of the decision

I remember when we discussed adding flush in the past, there were quite a few edge cases to consider

assert len(all_results) == num_sent


def test_mutations_batcher_exceptions(data_table, rows_to_delete):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can we add a test for RPC level error?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

gkevinzheng and others added 5 commits September 18, 2026 17:26
**Changes Made:**

- Replaced mutations batcher implementation with one based off of the
data client.

- Reworked unit tests.

- Added additional system tests.
@daniel-sanche
daniel-sanche force-pushed the shim/13-mutations-batcher branch from 57774e9 to 87f74b5 Compare September 19, 2026 00:28
@daniel-sanche
daniel-sanche marked this pull request as ready for review September 19, 2026 00:50
@daniel-sanche
daniel-sanche requested a review from a team as a code owner September 19, 2026 00:50

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants