Repository navigation
feat(gax): emit T4 attempt spans - #9496
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements OpenTelemetry trace context propagation into gRPC and HTTP/REST metadata within the gax package, introducing an isMetadata utility and a comprehensive test suite. The review feedback points out that plain object metadata should be cloned before injecting the active span context to prevent unintended mutations and trace context leakage.
c711b36 to
4bdc143
Compare
…er and createApiCall
…ntation libraries
7e54208 to
396dcd0
Compare
There was a problem hiding this comment.
Code Review
This pull request introduces Tier 4 (T4) per-attempt tracing spans (OpenTelemetry CLIENT spans) parented under the T3 client request spans in google-gax. It adds traceAttempt in TracerHelper.ts to manage individual RPC transport attempts, captures service path and port configurations in both gRPC and fallback clients, and updates unit tests to verify the new span relationships and attributes. Feedback on the changes highlights a critical issue in createApiCall.ts where mutating the outer func parameter inside invokeCall causes a memory leak and call stack growth across multiple API calls; a fix is suggested to wrap currentApiCaller instead.
…rs, and extract shared tracer helpers
🤖 I have created a release *beep* *boop* --- <details><summary>google-gax: 6.11.0</summary> ## [6.11.0](google-gax-v6.10.0...google-gax-v6.11.0) (2026-10-03) ### Features * **gax:** Emit T4 attempt spans ([#9496](#9496)) ([51aedce](51aedce)) ### Bug Fixes * **gax:** Propagate chunk granularity on resume and preserve retry error details ([#9480](#9480)) ([02b9478](02b9478)) </details> <details><summary>retry-request: 9.0.2</summary> ## [9.0.2](retry-request-v9.0.1...retry-request-v9.0.2) (2026-10-03) ### Bug Fixes * **retry-request:** Move teeny-request to devDependencies ([#9500](#9500)) ([068fe52](068fe52)) </details> <details><summary>test-utils: 0.2.0</summary> ## [0.2.0](test-utils-v0.1.0...test-utils-v0.2.0) (2026-10-03) ### Features * **test-utils:** Add runtime detection predicates and cross-engine assertion helpers ([#9492](#9492)) ([f971bb5](f971bb5)) </details> <details><summary>chat: 0.34.0</summary> ## [0.34.0](chat-v0.33.1...chat-v0.34.0) (2026-10-03) ### Features * Update API sources and regenerate ([#9481](#9481)) ([35a2b9a](35a2b9a)) </details> <details><summary>aiplatform: 7.5.0</summary> ## [7.5.0](aiplatform-v7.4.1...aiplatform-v7.5.0) (2026-10-03) ### Features * Update API sources and regenerate ([#9481](#9481)) ([35a2b9a](35a2b9a)) </details> <details><summary>bigtable-api: 0.10.0</summary> ## [0.10.0](bigtable-api-v0.9.0...bigtable-api-v0.10.0) (2026-10-03) ### Features * Update API sources and regenerate ([#9427](#9427)) ([5cd945d](5cd945d)) * Update API sources and regenerate ([#9472](#9472)) ([514e2f6](514e2f6)) </details> <details><summary>procurement: 0.10.0</summary> ## [0.10.0](procurement-v0.9.1...procurement-v0.10.0) (2026-10-03) ### Features * Update API sources and regenerate ([#9481](#9481)) ([35a2b9a](35a2b9a)) </details> <details><summary>commerceproducer: 0.6.0</summary> ## [0.6.0](commerceproducer-v0.5.0...commerceproducer-v0.6.0) (2026-10-03) ### Features * Update API sources and regenerate ([#9481](#9481)) ([35a2b9a](35a2b9a)) </details> <details><summary>compute: 7.7.0</summary> ## [7.7.0](compute-v7.6.0...compute-v7.7.0) (2026-10-03) ### Features * Update API sources and regenerate ([#9481](#9481)) ([35a2b9a](35a2b9a)) * Update Compute v1 API to version 2026-09-01 ([#9503](#9503)) ([02e3361](02e3361)) ### Bug Fixes * All AggregatedList RPCs behavior is now return_partial_success=true ([02e3361](02e3361)) * All AggregatedList RPCs return_partial_success fields removed ([02e3361](02e3361)) </details> <details><summary>products: 0.12.0</summary> ## [0.12.0](products-v0.11.1...products-v0.12.0) (2026-10-03) ### Features * Update API sources and regenerate ([#9481](#9481)) ([35a2b9a](35a2b9a)) </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>
…9539) ### Summary Fixes the `@google-cloud/pubsub` pack-and-install system test failure (`should be able to use the d.ts`): ``` node_modules/@google-cloud/pubsub/build/src/pubsub.d.ts:29:18 - error TS2430: Interface 'ClientConfig' incorrectly extends interface 'GrpcClientOptions'. Types of property 'port' are incompatible. Type 'string | number | undefined' is not assignable to type 'number | undefined'. Type 'string' is not assignable to type 'number'. ``` ### Root Cause In #9496 (released in `google-gax@6.11.0`), `GrpcClientOptions` added `port?: number;`. In `@google-cloud/pubsub`, `ClientConfig` extends `gax.GrpcClientOptions` but declared `port?: string | number;`, causing TypeScript compilation with `skipLibCheck: false` to fail when resolving `google-gax@6.11.0+`. Internally, `PubSub#determineBaseUrl_` already parses `port` as a `number` (or `undefined`), matching `gax.GrpcClientOptions` and `gax.ClientOptions`. ### Changes - Updated `ClientConfig.port` in `handwritten/pubsub/src/pubsub.ts` from `string | number` to `number`.
Widens `port` from `number` to `number | string` on `GrpcClientOptions` and `ClientStubOptions` in `google-gax` to restore type compatibility with downstream client libraries (such as `@google-cloud/pubsub`, whose `ClientConfig` extends `gax.GrpcClientOptions` with `port?: string | number`) #9496 added `port?: number` to `GrpcClientOptions` (released in `google-gax@6.11.0`). Because `@google-cloud/pubsub`'s `ClientConfig` interface extends `gax.GrpcClientOptions` and declares `port?: string | number`, TypeScript compilation with `skipLibCheck: false` (such as in `@google-cloud/pubsub`'s `system-test/install.ts`) fails
## Description This PR adds a lightweight, `pnpm`-based breaking-change check workflow as an alternative to the 1,764-line custom TypeScript AST/TypeChecker script in #9583, without adding any custom script files in `bin/`: 1. **Workspace dependent compilation via `pnpm --filter "...[HEAD^1...HEAD]"`**: Passes `--config.link-workspace-packages=deep --config.prefer-workspace-packages=true` to `pnpm` so modified `core/*` and `handwritten/*` packages are linked and compiled alongside their downstream workspace dependents (catching cross-package breakages like #9496 where a `google-gax` change broke `@google-cloud/pubsub`). 2. **Declaration comparison via `pnpm dlx @api-extractor-tools/change-detector`**: Emits `.d.ts` declarations for modified TypeScript files (`HEAD^1` vs `HEAD`) and runs `pnpm dlx @api-extractor-tools/change-detector /tmp/base.d.ts /tmp/head.d.ts --json`, flagging any removed exports/members (`action === 'removed'`) or narrowed types (`impact === 'narrowing'`). ## Impact - **CI / Pull Requests**: Automatically checks `core/*` and `handwritten/*` TypeScript changes for breaking public API changes and cross-package compilation regressions. - **Maintainability**: Only adds `.github/workflows/breaking-change-check.yaml` (113 lines) with zero custom `bin/breaking-change-check.mjs` code to maintain. ## Changes - [`.github/workflows/breaking-change-check.yaml`](.github/workflows/breaking-change-check.yaml): Compiles affected packages and workspace dependents via `pnpm --filter "...[HEAD^1...HEAD]"` and checks modified declarations using `pnpm dlx @api-extractor-tools/change-detector`. ## Testing - Verified against #9539 (`4443d6d6b1`) that `pnpm dlx @api-extractor-tools/change-detector` detects `Narrowed type of 'ClientConfig.port' from 'string | number' to 'number'` (`impact: "narrowing"`). - Verified against the revert in #9549 (`d62a64f338`) that widening `ClientConfig.port` back to `string | number` is classified as `impact: "widening"` and passes with zero errors. - Verified `pnpm --config.link-workspace-packages=deep --config.prefer-workspace-packages=true --filter "...[17978e7^1...17978e7]" --filter "!./packages/*"` discovers `@google-cloud/pubsub` and all other `core/*` and `handwritten/*` dependents of `google-gax` (#9496). ## Alternatives - **1,764-line custom AST/TypeChecker script in `bin/breaking-change-check.mjs` (#9583)**: Requires maintaining custom AST transformation passes, custom module resolution, and undocumented internal TypeScript `TypeChecker` calls inside this repository.

Emits OpenTelemetry tracing spans per-attempt transport spans (
SpanKind.CLIENT) directly fromgoogle-gaxfor both gRPC and HTTP/REST fallback callsKey Changes:
traceAttempt()andAttemptTraceContextto wrap each individual transport attempt (<apiName>/<methodName>,SpanKind.CLIENT), parented to the enclosing T3 client call span (<ClientName>.<MethodName>,SpanKind.INTERNAL)gcp.client.service/rpc.system,rpc.method/http.request.method,url.domain,server.address,server.port,gcp.grpc.resend_count/http.request.resend_count,error.type, span error status, andexceptionevents on attempt failuresservicePath/apiEndpointandportfromGrpcClientoptions intoconstructSettingsotherArgsso static trace context resolves custom endpoints and portstraceAttempt, T3/T4 parent-child hierarchies across unary, retries, and streaming calls, HTTP verb resolution, and transport-specific status code attributes