Skip to content

feat(x-goog-spanner-request-id): implement Request-ID #1264

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

Open
wants to merge 30 commits into
base: main
Choose a base branch
from

Conversation

odeke-em
Copy link
Contributor

Implements x-goog-spanner-request-id propagation for end-to-end debugging.

Fixes #1261

@product-auto-label product-auto-label bot added the size: m Pull request size is medium. label Dec 11, 2024
Copy link

conventional-commit-lint-gcf bot commented Dec 11, 2024

🤖 I detect that the PR title and the commit message differ and there's only one commit. To use the PR title for the commit history, you can use Github's automerge feature with squashing, or use automerge label. Good luck human!

-- conventional-commit-lint bot
https://conventionalcommits.org/

@product-auto-label product-auto-label bot added the api: spanner Issues related to the googleapis/python-spanner API. label Dec 11, 2024
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from 2451afe to 4f1da67 Compare December 12, 2024 08:13
@odeke-em odeke-em changed the title feat(x-goog-spanner-request-id): implement Requst-ID feat(x-goog-spanner-request-id): implement Request-ID Dec 12, 2024
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from b021c9e to 47da5e4 Compare December 14, 2024 13:13
@product-auto-label product-auto-label bot added size: l Pull request size is large. and removed size: m Pull request size is medium. labels Dec 14, 2024
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from 8616572 to caa60c2 Compare December 16, 2024 12:23
odeke-em added a commit to odeke-em/python-spanner that referenced this pull request Dec 18, 2024
This change introduces AtomicCounter, a concurrency/thread-safe
counter do deal with the multi-threaded nature of variables.
It permits operations:
* atomic_counter += 1
* value = atomic_counter + 1
* atomic_counter.value

that'll be paramount to bringing in the logic for
x-goog-spanner-request-id in much reduced changelists.

Updates googleapis#1261
Carved out from PR googleapis#1264
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from 9903cac to 529333a Compare December 18, 2024 14:25
@odeke-em odeke-em marked this pull request as ready for review December 18, 2024 14:26
@odeke-em odeke-em requested review from a team as code owners December 18, 2024 14:26
@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. and removed size: l Pull request size is large. labels Dec 19, 2024
@olavloite olavloite added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 19, 2024
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 19, 2024
olavloite added a commit that referenced this pull request Dec 19, 2024
* feat(x-goog-spanner-request-id): introduce AtomicCounter

This change introduces AtomicCounter, a concurrency/thread-safe
counter do deal with the multi-threaded nature of variables.
It permits operations:
* atomic_counter += 1
* value = atomic_counter + 1
* atomic_counter.value

that'll be paramount to bringing in the logic for
x-goog-spanner-request-id in much reduced changelists.

Updates #1261
Carved out from PR #1264

* Tests for with_request_id

* chore: remove sleep

* chore: remove unused import

---------

Co-authored-by: Knut Olav Løite <[email protected]>
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from 2d6a3ea to 65757b5 Compare December 20, 2024 05:37
@@ -698,10 +728,20 @@ def execute_partitioned_dml(
_metadata_with_leader_aware_routing(self._route_to_leader_enabled)
)

# Attempt will be incremented inside _restart_on_unavailable.
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume that this comment applies to partial_attempt, no? If so, can we move it down to that variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It applies to begin_txn_attempt and I've updated the comment and moving the comment before the variable itself. Thank you.

trace_name="CloudSpanner.ExecuteStreamingSql",
request=request,
transaction_selector=txn_selector,
observability_options=self.observability_options,
attempt=begin_txn_attempt,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that this should be partial_attempt. Retries of this RPC will not retry the BeginTransaction RPC, it will just continue to use the same transaction ID as the one that was returned by the original BeginTransaction RPC.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oooh, okay, that's very interesting and thanks for letting me know, let me make that update.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did however already pass in and increment partial_attempt inside wrapped_method. I'll instead remove that and increment them in the appropriate sites.

]
assert got_stream_segments == want_stream_segments

def test_database_run_in_transaction_retries_on_abort(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

This test does not appear to actually verify anything (other than that it does not cause any errors). Can we either remove it, or add verifications for the scenario it should cover?

("x-goog-spanner-route-to-leader", "true"),
(
"x-goog-spanner-request-id",
f"1.{REQ_RAND_PROCESS_ID}.{database.NTH_CLIENT.value}.1.2.2",
Copy link
Contributor

Choose a reason for hiding this comment

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

Is attempt set to 2 here because the transaction is retried? If so, then that is not correct. The attempt number should only be increased if the RPC itself is being retried due to a retryable error for that (single) RPC. E.g. if a ServiceUnavailable error is returned.

("x-goog-spanner-route-to-leader", "true"),
(
"x-goog-spanner-request-id",
f"1.{REQ_RAND_PROCESS_ID}.{database.NTH_CLIENT.value}.1.3.2",
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here as for the BeginTransaction RPC: Transaction retries should not increase the attempt count. Only retries of a single RPC due to UNAVAILABLE errors (and other retryable error codes).

@olavloite olavloite added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 24, 2024
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 24, 2024
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from f8e0717 to 7fc3f3f Compare December 24, 2024 21:54
@olavloite olavloite added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 25, 2024
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 25, 2024
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from 07a00f9 to 70eeaef Compare December 25, 2024 14:03
@olavloite olavloite added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 26, 2024
return orig_getattribute(obj, key, *args, **kwargs)

attr = orig_getattribute(obj, key, *args, **kwargs)
print("args", args, "attr.dir", dir(attr))
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: remove

if mangled_or_private:
return attr

print("\033[35mattr", attr, "hex_id", hex(id(attr)), "\033[00m")
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: remove

Copy link
Contributor

Choose a reason for hiding this comment

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

here and everywhere: remove print statements

@@ -246,6 +246,7 @@ def bind(self, database):
observability_options=observability_options,
metadata=metadata,
) as span, MetricsCapture():
attempt = 1
Copy link
Contributor

Choose a reason for hiding this comment

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

This variable can (still) be removed, as it is unused.

metadata = _metadata_with_prefix(self._database.name)
database = self._database
api = database.spanner_api
database = self._database
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: remove, it is already assigned two lines above

Comment on lines 572 to 573
if not isinstance(nth_request, int):
raise Exception(f"failed to get an integer back: {nth_request}")
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 this here, but not in the read function above?

def test_streaming_retryable_error(self):
add_select1_result()
add_error(SpannerServicer.ExecuteStreamingSql.__name__, unavailable_status())
add_error(SpannerServicer.ExecuteStreamingSql.__name__, unavailable_status())
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I think that adding one error is enough

@olavloite olavloite added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Mar 25, 2025
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Mar 25, 2025
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from 4484cfd to 3bda544 Compare March 28, 2025 11:23
@odeke-em odeke-em requested a review from olavloite March 28, 2025 11:24
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from 3bda544 to f8ad94f Compare March 28, 2025 11:27
@sakthivelmanii sakthivelmanii added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Mar 28, 2025
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Mar 28, 2025
@sakthivelmanii sakthivelmanii added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Apr 1, 2025
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Apr 1, 2025
odeke-em added a commit to odeke-em/python-spanner that referenced this pull request Apr 30, 2025
This change commits the scaffolding for which testing
will be used. This is a carve out of PRs googleapis#1264 and googleapis#1364,
meant to make those changes lighter and much easier to
review then merge.

Updates googleapis#1261
odeke-em added a commit to odeke-em/python-spanner that referenced this pull request Apr 30, 2025
This change commits the scaffolding for which testing
will be used. This is a carve out of PRs googleapis#1264 and googleapis#1364,
meant to make those changes lighter and much easier to
review then merge.

Updates googleapis#1261
odeke-em added a commit to odeke-em/python-spanner that referenced this pull request Apr 30, 2025
This change commits the scaffolding for which testing
will be used. This is a carve out of PRs googleapis#1264 and googleapis#1364,
meant to make those changes lighter and much easier to
review then merge.

Updates googleapis#1261
odeke-em added a commit to odeke-em/python-spanner that referenced this pull request May 2, 2025
This change commits the scaffolding for which testing
will be used. This is a carve out of PRs googleapis#1264 and googleapis#1364,
meant to make those changes lighter and much easier to
review then merge.

Updates googleapis#1261
olavloite pushed a commit that referenced this pull request May 7, 2025
* chore(x-goog-request-id): commit testing scaffold

This change commits the scaffolding for which testing
will be used. This is a carve out of PRs #1264 and #1364,
meant to make those changes lighter and much easier to
review then merge.

Updates #1261

* Use guard to keep x-goog-request-id interceptor docile in tests until activation later

* AtomicCounter update

* Remove duplicate unavailable_status that had been already committed into main
@product-auto-label product-auto-label bot added size: l Pull request size is large. and removed size: xl Pull request size is extra large. labels May 17, 2025
@odeke-em odeke-em force-pushed the x-goog-spanner-request-id branch from 6fe1810 to dab92dd Compare May 19, 2025 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: spanner Issues related to the googleapis/python-spanner API. size: l Pull request size is large.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement propagation of x-goog-spanner-request-id gRPC header on every call
5 participants