Skip to content

fix(spanner): record streaming operation completion when stream finishes - #18704

Draft
sinhasubham wants to merge 1 commit into
mainfrom
fix-operation-latency
Draft

sinhasubham wants to merge 1 commit into
mainfrom
fix-operation-latency

Conversation

@sinhasubham

Copy link
Copy Markdown
Contributor

Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Make sure to open an issue as a bug/issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Code coverage does not decrease (if any source code was changed)
  • Appropriate docs were updated (if necessary)

Fixes #<issue_number_goes_here> 🦕

@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 Spanner client's metrics tracking to ensure that streaming operation latencies are recorded immediately upon stream completion and exclude consumer processing delays. This is achieved by tracking stream completion in both synchronous and asynchronous snapshot iterators and recording metrics accordingly. However, the reviewer identified a critical issue in metrics_interceptor.py where the code attempts to check for a last attribute on the yielded stream items. Since the production PartialResultSet protobuf messages do not contain a last field, this check will always evaluate to False and act as dead code. It is recommended to remove these redundant checks.

Comment on lines +282 to +284
if getattr(item, "last", False) is True:
self._record_metrics()
return item

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.

high

In production, the item yielded by the gRPC response iterator is a PartialResultSet protobuf message (or a proto-plus wrapper). The PartialResultSet proto definition does not contain a last field. Therefore, getattr(item, "last", False) will always return False in production, making this check dead code that never executes.

The integration tests pass only because they fully consume the stream (e.g., using list(results) or for _ in results), which raises StopIteration and triggers _record_metrics() in the except StopIteration block.

Since there is no last field in the Spanner PartialResultSet proto, we should remove this check to avoid dead code and false assumptions about the protobuf structure.

        return item

Comment on lines +508 to +510
if getattr(item, "last", False) is True:
await self._record_metrics()
return item

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.

high

Similarly to the synchronous version, the item yielded by the async iterator is a PartialResultSet protobuf message, which does not have a last field. Thus, getattr(item, "last", False) will always return False in production. We should remove this check.

        return item

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.

1 participant