Skip to content
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

feat: add generated sync client #1017

Merged
merged 422 commits into from
Dec 12, 2024
Merged

Conversation

daniel-sanche
Copy link
Contributor

@daniel-sanche daniel-sanche commented Aug 30, 2024

This PR adds the sync version of the new data client to the codebase:

  • autogenerated sync files are created in _sync_autogen directories
  • added docs pages for new classes

verification tests moved to new PR, to keep this mostly generated code: #1046

Base automatically changed from cross_sync2_pr2_annotations to main November 20, 2024 00:41
@daniel-sanche daniel-sanche changed the title [DRAFT] feat: add generated sync client feat: add generated sync client Dec 3, 2024
@@ -305,7 +305,7 @@ async def append(self, mutation_entry: RowMutationEntry):
# TODO: return a future to track completion of this entry
if self._closed.is_set():
raise RuntimeError("Cannot append to closed MutationsBatcher")
if isinstance(mutation_entry, Mutation): # type: ignore
if isinstance(cast(Mutation, mutation_entry), Mutation):
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need cast() here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TL;DR: because comments aren't part of the ast, so # type: ignore doesn't make it through the generation process for the sync client. But typing.cast does the same thing, by forcing the type checker to treat it as a specific type here

For why we need to ignore the type in the first place: this is a check to raise a helpful error when the user passes in a Mutation instead of a RowMutationEntry, which could be an easy mistake to make. But the type checker doesn't like this check, since we're checking if it's a type that it knows it should never be

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the explanation!

gapic_client.mutate_rows,
table_name=table.table_name,
app_profile_id=table.app_profile_id,
retry=None,
Copy link
Contributor

Choose a reason for hiding this comment

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

what does this parameter do and why is it none?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This would be the gapic-level retry logic. We set it to None because we handle retries at a higher-level, retrying self._run_attempt instead (It's wrapped by CrossSync._Sync_Impl.retry_target into self._operation a few lines down)

self._handle_entry_error(orig_idx, entry_error)
elif orig_idx in self.errors:
del self.errors[orig_idx]
del active_request_indices[result.index]
Copy link
Contributor

Choose a reason for hiding this comment

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

this modifies the active request list, will line 149 orig_idx = active_request_indices[result.index] still be correct after a deletion? would result.index be > active_request_indices at some point?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

active_request_indices is a map, not a list. It maps indexes between the original overall request, and the latest attempt (which may be for a small subset of the original mutations)

We should never encounter a result.index that isn't in active_request_indices, because they are both derived from remaining_indices

@@ -0,0 +1,828 @@
# Copyright 2023 Google LLC
Copy link
Contributor

@mutianf mutianf Dec 6, 2024

Choose a reason for hiding this comment

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

this should be 2024 in all the files, wondering if it's because in async it's 2023..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I had the code generator copy over all header comments from the async files. Using a different year for the generated files would be tricky. And I thought since 90% of the files are the same, it makes sense to keep the same publication year, since it's closer to a copy than an original file. But maybe we should use a year range instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we change all 2023 to 2024 for now?

tests/unit/data/_async/test_client.py Show resolved Hide resolved
@daniel-sanche daniel-sanche merged commit f974823 into main Dec 12, 2024
29 of 32 checks passed
@daniel-sanche daniel-sanche deleted the cross_sync2_pr3_generated_sync branch December 12, 2024 21:41
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: xl Pull request size is extra large.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants