-
Notifications
You must be signed in to change notification settings - Fork 98
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
base: main
Are you sure you want to change the base?
Conversation
🤖 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 -- conventional-commit-lint bot |
2451afe
to
4f1da67
Compare
b021c9e
to
47da5e4
Compare
8616572
to
caa60c2
Compare
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
9903cac
to
529333a
Compare
* 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]>
2d6a3ea
to
65757b5
Compare
google/cloud/spanner_v1/database.py
Outdated
@@ -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. |
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.
I assume that this comment applies to partial_attempt
, no? If so, can we move it down to that variable.
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.
It applies to begin_txn_attempt
and I've updated the comment and moving the comment before the variable itself. Thank you.
google/cloud/spanner_v1/database.py
Outdated
trace_name="CloudSpanner.ExecuteStreamingSql", | ||
request=request, | ||
transaction_selector=txn_selector, | ||
observability_options=self.observability_options, | ||
attempt=begin_txn_attempt, |
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.
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.
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.
Oooh, okay, that's very interesting and thanks for letting me know, let me make that update.
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.
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.
tests/unit/test_request_id_header.py
Outdated
] | ||
assert got_stream_segments == want_stream_segments | ||
|
||
def test_database_run_in_transaction_retries_on_abort(self): |
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.
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?
tests/unit/test_session.py
Outdated
("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", |
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.
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.
tests/unit/test_session.py
Outdated
("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", |
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.
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).
f8e0717
to
7fc3f3f
Compare
07a00f9
to
70eeaef
Compare
google/cloud/spanner_v1/_helpers.py
Outdated
return orig_getattribute(obj, key, *args, **kwargs) | ||
|
||
attr = orig_getattribute(obj, key, *args, **kwargs) | ||
print("args", args, "attr.dir", dir(attr)) |
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.
nit: remove
google/cloud/spanner_v1/_helpers.py
Outdated
if mangled_or_private: | ||
return attr | ||
|
||
print("\033[35mattr", attr, "hex_id", hex(id(attr)), "\033[00m") |
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.
nit: remove
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.
here and everywhere: remove print
statements
google/cloud/spanner_v1/pool.py
Outdated
@@ -246,6 +246,7 @@ def bind(self, database): | |||
observability_options=observability_options, | |||
metadata=metadata, | |||
) as span, MetricsCapture(): | |||
attempt = 1 |
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.
This variable can (still) be removed, as it is unused.
google/cloud/spanner_v1/session.py
Outdated
metadata = _metadata_with_prefix(self._database.name) | ||
database = self._database | ||
api = database.spanner_api | ||
database = self._database |
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.
nit: remove, it is already assigned two lines above
google/cloud/spanner_v1/snapshot.py
Outdated
if not isinstance(nth_request, int): | ||
raise Exception(f"failed to get an integer back: {nth_request}") |
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.
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()) |
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.
nit: I think that adding one error is enough
4484cfd
to
3bda544
Compare
3bda544
to
f8ad94f
Compare
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
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
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
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
* 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
6fe1810
to
dab92dd
Compare
Implements x-goog-spanner-request-id propagation for end-to-end debugging.
Fixes #1261