Skip to content

fix(spanner): scope server-timing metrics per call and guard interceptor lifecycle callbacks - #14053

Merged
olavloite merged 1 commit into
mainfrom
spanner-fix-race-in-header-interceptor
Aug 12, 2026
Merged

fix(spanner): scope server-timing metrics per call and guard interceptor lifecycle callbacks#14053
olavloite merged 1 commit into
mainfrom
spanner-fix-race-in-header-interceptor

Conversation

@olavloite

Copy link
Copy Markdown
Contributor
  • Scope gfeLatency and afeLatency to per-call listener instances in HeaderInterceptor to eliminate data races and cross-RPC telemetry pollution.
  • Guard onHeaders and onClose in HeaderInterceptor with try...finally to guarantee downstream callback propagation (preventing hung futures) and RequestIdTargetTracker cleanup.
  • Catch Throwable in SpannerErrorInterceptor.onClose to prevent unexpected metadata parsing errors from escaping into gRPC transport threads.

The above changes should guarantee that all interceptors in the entire chain of interceptors are always executed, and that no exceptions escape to the gRPC thread executing them.

@olavloite
olavloite requested review from a team as code owners August 12, 2026 08:22

@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 HeaderInterceptor to make it thread-safe by moving latency state variables from the class level to the call listener level. It also enhances robustness in both HeaderInterceptor and SpannerErrorInterceptor by wrapping header and close processing in try-catch-finally blocks, ensuring downstream gRPC notifications are always executed even if unexpected exceptions occur. Additionally, comprehensive unit tests are introduced for both interceptors to verify their behavior and error handling. I have no feedback to provide as there are no review comments.

…tor lifecycle callbacks

- Scope gfeLatency and afeLatency to per-call listener instances in HeaderInterceptor to eliminate data races and cross-RPC telemetry pollution.
- Guard onHeaders and onClose in HeaderInterceptor with try...finally to guarantee downstream callback propagation (preventing hung futures) and RequestIdTargetTracker cleanup.
- Catch Throwable in SpannerErrorInterceptor.onClose to prevent unexpected metadata parsing errors from escaping into gRPC transport threads.

The above changes should guarantee that all interceptors in the entire chain of interceptors
are always executed, and that no exceptions escape to the gRPC thread executing them.
@olavloite
olavloite force-pushed the spanner-fix-race-in-header-interceptor branch from ff9bece to 01b12f6 Compare August 12, 2026 08:37
@olavloite olavloite added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Aug 12, 2026
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Aug 12, 2026
@olavloite
olavloite merged commit f35c570 into main Aug 12, 2026
205 checks passed
@olavloite
olavloite deleted the spanner-fix-race-in-header-interceptor branch August 12, 2026 09:58
lqiu96 pushed a commit that referenced this pull request Aug 24, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>1.90.0</summary>

##
[1.90.0](v1.89.0...v1.90.0)
(2026-08-24)


### Features

* **bigquery-jdbc:** implement TypeRegistry and TypeDescriptor
([#13947](#13947))
([0557e69](0557e69))
* **bigquery:** add QueryResultsFormat and ArrowSerializationOptions
configurations
([#13942](#13942))
([ff03e19](ff03e19))
* **bigquery:** expose `StatementType` and query execution stats on
`TableResult`
([#14145](#14145))
([7d16de8](7d16de8))
* **bigtable:** enable microsecond timestamps in client
([#14057](#14057))
([57aaf8d](57aaf8d))
* **bigtable:** route single-entry MutateRows through a point-write c…
([#14028](#14028))
([a403703](a403703))
* **datastore:** add support for request tags
([#13732](#13732))
([b1f6186](b1f6186))
* **ftp:** onboard a new library
([#14068](#14068))
([f41b2d9](f41b2d9))
* **gax:** add ResumableUploadCallable and ResumableUploadCallSettings
([#14052](#14052))
([a5e26e8](a5e26e8))
* **google/cloud/biglake/hive/v1:** onboard a new library
([#14130](#14130))
([650c839](650c839))
* **google/maps/mapmanagement/v2:** onboard a new library
([#14131](#14131))
([7d00726](7d00726))
* **spanner:** support user-provided OpenTelemetry for client metrics
export
([#13741](#13741))
([da74dee](da74dee))
* update API sources and regenerate
([#14000](#14000))
([9337a93](9337a93))
* **workloadidentity:** onboard a new library
([#14060](#14060))
([ab226ee](ab226ee))


### Bug Fixes

* add documentation for insertall api that there's no default retry
([#13953](#13953))
([1fdb4f1](1fdb4f1))
* add retry behavior documentation to insertall interface to clarify the
behavior
([#14058](#14058))
([1b8f9e3](1b8f9e3))
* **auth:** fix JSpecify nullability in UserAuthorizer and TokenStore
([#14150](#14150))
([0d5fac0](0d5fac0))
* **auth:** fix remaining nullability in UserAuthorizer and Builder
([#14158](#14158))
([a51bb8d](a51bb8d))
* **auth:** refine JSpecify nullability for ServiceAccountCredentials
and UserCredentials
([#14159](#14159))
([a929250](a929250))
* **bigquery-jdbc:** enable ITOpenTelemetryTest
([#13991](#13991))
([fa6641b](fa6641b))
* **bigquery-jdbc:** pass connection proxy settings to OpenTelemetry
exporters
([#14011](#14011))
([115b9b3](115b9b3))
* **bigquery-jdbc:** session context propagation when session is enabled
([#14161](#14161))
([1e74dda](1e74dda))
* **bigtable:** remove heartbeat miss logging
([#14054](#14054))
([ec17637](ec17637))
* **deps:** update dependency
com.google.apis:google-api-services-bigquery to v2-rev20260731-2.0.0
([#14149](#14149))
([95f6c38](95f6c38))
* **deps:** update dependency com.google.cloud:libraries-bom to v26.86.0
([#14103](#14103))
([cf5697e](cf5697e))
* **gax-httpjson:** reduce Conscrypt fallback error to debug level
([#13962](#13962))
([8236771](8236771))
* **gax-httpjson:** remove unsupported and deprecated PQC named groups
([#14107](#14107))
([7604971](7604971))
* **gax:** register Conscrypt SSLContext SPI classes for GraalVM
reflection
([#14129](#14129))
([73c0243](73c0243))
* **samples:** align native profile junit and surefire versions with
shared config
([#14096](#14096))
([2b84133](2b84133))
* **spanner:** add closeAsync to ReadContext and make transaction
closing non-blocking
([#14076](#14076))
([671f892](671f892))
* **spanner:** scope server-timing metrics per call and guard
interceptor lifecycle callbacks
([#14053](#14053))
([f35c570](f35c570))
* **storage:** use JsonUtils for StorageObject serialization in
resumable writes and read channels
([#13976](#13976))
([d94922f](d94922f))


### Performance Improvements

* **bigquery-jdbc:** eliminate dry run to resolve statement type
([#14156](#14156))
([7109ecd](7109ecd))
* **spanner-jdbc:** cache commonly used query parameter names
([#14036](#14036))
([1eb6aa3](1eb6aa3))
* **spanner-jdbc:** cache JDBC metadata query strings
([#14041](#14041))
([31c628f](31c628f))
* **spanner-jdbc:** cache positional to named param conversion
([#14034](#14034))
([30e031b](30e031b))


### Dependencies

* **gax-httpjson:** upgrade conscrypt-openjdk-uber to 2.6.2
([#14117](#14117))
([2f5481a](2f5481a))
* Update gRPC to v1.82.3
([#13997](#13997))
([a786107](a786107))
* Upgrade gRPC to v1.82.4
([#14088](#14088))
([0c482fe](0c482fe))


### Documentation

* **bigquery-jdbc:** add user guide with connection property and custom
endpoint reference
([#13878](#13878))
([2dde172](2dde172))
* **gax:** update LRO troubleshooting documentation link
([#14108](#14108))
([4c5bbae](4c5bbae))
* **spanner-jdbc:** update connection_properties.md documentation
([#14035](#14035))
([b576fe8](b576fe8))
* **spanner:** update CHANGELOG.md for releases 6.117.0 through 6.120.0
([#13970](#13970))
([2413811](2413811))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
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