Skip to content

feat(bigtable): add debug tag counter (recordDebugTag / assertDebugTag) - #20114

Merged
sushanb merged 4 commits into
googleapis:mainfrom
sushanb:bigtable-session-core-debug-tracer
Jul 9, 2026
Merged

feat(bigtable): add debug tag counter (recordDebugTag / assertDebugTag)#20114
sushanb merged 4 commits into
googleapis:mainfrom
sushanb:bigtable-session-core-debug-tracer

Conversation

@sushanb

@sushanb sushanb commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the transport-package debug-tag counter used at "this branch shouldn't reach" sites in the Session, session pool, and configuration manager. Every emission is one atomic add plus one OTel Int64Counter increment; safe to sprinkle freely on cold paths. Metric name (debug_tags) matches java-bigtable's ClientDebugTagCount so cross-language dashboards join on the tag column.

Provides:

  • recordDebugTag(name) — cheap observation counter (Warn level).
  • recordDebugTagAt(level, name) — same, with an explicit level.
  • assertDebugTag(expr, name) / assertDebugTagf — invariant checks that increment the counter and log at Error level when they fail.
  • DebugTags() + snapshotDebugTagCounts() — read-side for debug pages.
  • Tag catalog constants (tagSession*, tagVRPC*, etc.) referenced from Session-lifecycle and vRPC code in the follow-up PR.

Standalone — the Session/vRPC code that emits these tags lands in the Session core PR (#20112) stacked on top. Independent of #20115 (metrics TransportTypeName export); the two can merge in any order.

Part 2/3 of the Session core split.

Test plan

  • go build ./bigtable/...
  • go vet ./bigtable/internal/transport/...
  • CI: presubmit (dedicated debug_tracer_test.go lands in a follow-up along with a broader test-only split)

@sushanb
sushanb requested review from a team as code owners July 8, 2026 23:40
@product-auto-label product-auto-label Bot added the api: bigtable Issues related to the Bigtable API. label Jul 8, 2026

@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 introduces two new files in the bigtable/internal/transport package: debug_tracer.go, which implements a lightweight tracer for unexpected events using OTel metrics and in-memory stats, and transport_type_name.go, which maps transport type enums to short string labels. The code review feedback highlights a critical data race on the global debugTagCounter interface, suggesting the use of atomic.Value for thread-safe operations. Additionally, it recommends renaming bumpDebugTagCountLocked to remove the misleading Locked suffix and optimizing lock hold times in DebugTags by releasing the read lock before sorting the local slice.

Comment thread bigtable/internal/transport/debug_tracer.go Outdated
Comment thread bigtable/internal/transport/debug_tracer.go Outdated
Comment thread bigtable/internal/transport/debug_tracer.go Outdated
Comment thread bigtable/internal/transport/debug_tracer.go Outdated
Comment thread bigtable/internal/transport/debug_tracer.go Outdated
Comment thread bigtable/internal/transport/debug_tracer.go
@sushanb
sushanb force-pushed the bigtable-session-core-debug-tracer branch from b728bf6 to 5e1d21b Compare July 8, 2026 23:43
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
Adds the Session struct itself along with the two "surface" halves that
have no lifecycle behavior of their own — the OTel tracer and the
in-process debug counters / event ring. Also adds SessionHandle, the
per-session slot the pool checkout / picker code holds. Lifecycle
(Start / Close / readLoop / heartBeatLoop) and vRPC (Invoke) come next
in the reshaped googleapis#20112.

- session.go — Session struct + hooks + NewSession + State
  transitions (transitionTo, is/notState, signalQuiescent), vrpcResult,
  sessionErr, unavailable, afeID. Uses the existing State enum from
  session_state.go (PR googleapis#19981) — no re-declaration.
- session_debug.go — embedded sessionDebug: counters (retries, okRpcs,
  errorRpcs, msgsSent, msgsRecv), per-session event ring, latency
  histogram, cluster-id map, WithSessionLogger / WithSessionPoolName
  options, RemoteAddr / SampleUptime / RecordTransportOverhead
  accessors. Consumes metrics.TransportTypeName (googleapis#20115) and
  recordDebugTag (googleapis#20114).
- session_tracer.go — OTel sessionTracer for per-session +
  per-attempt metrics (session duration, open latency, uptime,
  transport-overhead histogram). Consumes metrics.TransportTypeName.
- picker.go — SessionHandle wrapping *Session with the per-pick
  counters (Picks, Outstanding, LastActivity) the pool needs. Its
  concrete users (SessionPool, AFE picker) come in later PRs; the
  handle type is here because Session embeds an atomic.Pointer to it.

Part 3b/3c of the Session core sub-split. Stacks on
bigtable-session-primitives (Part 3a), googleapis#20115
(metrics.TransportTypeName export), and googleapis#20114 (debug tag counter).
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
Adds the behavior half of the Session — the lifecycle state machine,
the vRPC dispatch path, and the fake-driven test suite that exercises
both. Together with the struct + surface half (bigtable-session-struct)
and the primitives (bigtable-session-primitives), this completes the
Session core.

- session_lifecycle.go — Start, ForceClose, Close, Send, readLoop,
  heartBeatLoop, handleOpenSession / handleErrorResponse /
  handleGoAway / handleClose / handleSessionParameters,
  peerInfoExtracter.
- session_vrpc.go — Invoke, buildInvokeRequest, awaitInvokeResult,
  handleVRPCResponse / handleVRPCErrorResponse, deliver,
  cancelActiveRPCs, noteRetryAttempt, releaseSlot.
- session_test.go — fakeStream / fakeDesc plus tests for
  handleOpenSession, handleVRPC*, handleGoAway, handleErrorResponse,
  Invoke, ForceClose, Close, heartBeatLoop, PeerInfo extraction,
  AfeID, Start.

Also folds in the pending gemini-code-assist review findings so this
PR merges without a follow-up:

- Fire onStart immediately after transitionTo(StateStarting) so the
  "onStart precedes onClose" invariant holds even when Send fails and
  ForceClose fires onClose.
- Nil-guard handleErrorResponse / handleSessionParameters /
  handleVRPCResponse / handleVRPCErrorResponse and the res.resp branch
  in awaitInvokeResult; drop instead of panicking in the readLoop
  goroutine.
- Retag pre-wire Send failures in Invoke as StateUncommitted (was
  StateTransportFailure) so the retry interceptor can retry
  non-idempotent ops when the frame never reached the server — Java
  parity with java-bigtable's classification.

Part 3c of 3 in the Session core sub-split. Stacks on
bigtable-session-struct (Part 3b), bigtable-session-primitives (Part
3a), googleapis#20115 (metrics.TransportTypeName), and googleapis#20114 (debug tag counter).
@sushanb sushanb changed the title feat(bigtable): add debug tag counter (recordDebugTag / assertDebugTag) [2/5] feat(bigtable): add debug tag counter (recordDebugTag / assertDebugTag) Jul 9, 2026
Adds the transport-package debug-tag counter used at "this branch
shouldn't reach" sites in the Session, session pool, and configuration
manager. Every emission is one atomic add plus one OTel Int64Counter
increment; safe to sprinkle freely on cold paths. Metric name (`debug_tags`)
matches java-bigtable's `ClientDebugTagCount` so cross-language
dashboards join on the tag column.

Provides:

- `recordDebugTag(name)` — cheap observation counter (Warn level).
- `recordDebugTagAt(level, name)` — same, with an explicit level.
- `assertDebugTag(expr, name)` / `assertDebugTagf` — invariant checks
  that increment the counter and log at Error level when they fail.
- `DebugTags()` + `snapshotDebugTagCounts()` — read-side for debug pages.
- Tag catalog constants (`tagSession*`, `tagVRPC*`, etc.) referenced
  from Session-lifecycle and vRPC code in the follow-up PRs.

Standalone — the Session/vRPC code that emits these tags lands in the
Session core PR stacked on top.

**Part 2/3 of the Session core split.** Stacked on googleapis#20113 (TransportTypeName).
@sushanb
sushanb force-pushed the bigtable-session-core-debug-tracer branch from 5e1d21b to 27fd0bf Compare July 9, 2026 00:15
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
…type)

Adds the standalone types that the Session struct and its lifecycle /
vRPC / debug halves all depend on. Each file is self-contained (no
cross-references) so this PR compiles and passes tests on its own.

- attempt_outcome.go — AttemptState (StateUncommitted /
  StateTransportFailure / StateServerResult), tagErr, TagErr,
  ClassifyErr. Models Java's VRpc.VRpcResult.State so the RetryingVRpc
  interceptor (later PR) can classify errors the same way as
  java-bigtable.
- vrpc.go — ctx-metadata helpers (WithVRpcMetadata, WithAttempt,
  VRpcAttempt, VRpcMethod, WithPrevAttemptErr, PrevAttemptErr). Session
  Invoke reads these from its ctx.
- session_msgtype.go — reqMsgType / respMsgType enums + classifyReq /
  classifyResp helpers. Used by the debug surface + tracer to bucket
  Session request/response types.

Part 3a/3c of the Session core sub-split (a follow-up to the original
Session core PR googleapis#20112, which is being reshaped into three thinner
PRs). Stacks on googleapis#20115 (metrics.TransportTypeName export) and googleapis#20114
(debug tag counter); each of those can merge in any order.
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
Adds the Session struct itself along with the two "surface" halves that
have no lifecycle behavior of their own — the OTel tracer and the
in-process debug counters / event ring. Also adds SessionHandle, the
per-session slot the pool checkout / picker code holds. Lifecycle
(Start / Close / readLoop / heartBeatLoop) and vRPC (Invoke) come next
in the reshaped googleapis#20112.

- session.go — Session struct + hooks + NewSession + State
  transitions (transitionTo, is/notState, signalQuiescent), vrpcResult,
  sessionErr, unavailable, afeID. Uses the existing State enum from
  session_state.go (PR googleapis#19981) — no re-declaration.
- session_debug.go — embedded sessionDebug: counters (retries, okRpcs,
  errorRpcs, msgsSent, msgsRecv), per-session event ring, latency
  histogram, cluster-id map, WithSessionLogger / WithSessionPoolName
  options, RemoteAddr / SampleUptime / RecordTransportOverhead
  accessors. Consumes metrics.TransportTypeName (googleapis#20115) and
  recordDebugTag (googleapis#20114).
- session_tracer.go — OTel sessionTracer for per-session +
  per-attempt metrics (session duration, open latency, uptime,
  transport-overhead histogram). Consumes metrics.TransportTypeName.
- picker.go — SessionHandle wrapping *Session with the per-pick
  counters (Picks, Outstanding, LastActivity) the pool needs. Its
  concrete users (SessionPool, AFE picker) come in later PRs; the
  handle type is here because Session embeds an atomic.Pointer to it.

Part 3b/3c of the Session core sub-split. Stacks on
bigtable-session-primitives (Part 3a), googleapis#20115
(metrics.TransportTypeName export), and googleapis#20114 (debug tag counter).
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
Adds the behavior half of the Session — the lifecycle state machine,
the vRPC dispatch path, and the fake-driven test suite that exercises
both. Together with the struct + surface half (bigtable-session-struct)
and the primitives (bigtable-session-primitives), this completes the
Session core.

- session_lifecycle.go — Start, ForceClose, Close, Send, readLoop,
  heartBeatLoop, handleOpenSession / handleErrorResponse /
  handleGoAway / handleClose / handleSessionParameters,
  peerInfoExtracter.
- session_vrpc.go — Invoke, buildInvokeRequest, awaitInvokeResult,
  handleVRPCResponse / handleVRPCErrorResponse, deliver,
  cancelActiveRPCs, noteRetryAttempt, releaseSlot.
- session_test.go — fakeStream / fakeDesc plus tests for
  handleOpenSession, handleVRPC*, handleGoAway, handleErrorResponse,
  Invoke, ForceClose, Close, heartBeatLoop, PeerInfo extraction,
  AfeID, Start.

Also folds in the pending gemini-code-assist review findings so this
PR merges without a follow-up:

- Fire onStart immediately after transitionTo(StateStarting) so the
  "onStart precedes onClose" invariant holds even when Send fails and
  ForceClose fires onClose.
- Nil-guard handleErrorResponse / handleSessionParameters /
  handleVRPCResponse / handleVRPCErrorResponse and the res.resp branch
  in awaitInvokeResult; drop instead of panicking in the readLoop
  goroutine.
- Retag pre-wire Send failures in Invoke as StateUncommitted (was
  StateTransportFailure) so the retry interceptor can retry
  non-idempotent ops when the frame never reached the server — Java
  parity with java-bigtable's classification.

Part 3c of 3 in the Session core sub-split. Stacks on
bigtable-session-struct (Part 3b), bigtable-session-primitives (Part
3a), googleapis#20115 (metrics.TransportTypeName), and googleapis#20114 (debug tag counter).
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
…type)

Adds the standalone types that the Session struct and its lifecycle /
vRPC / debug halves all depend on. Each file is self-contained (no
cross-references) so this PR compiles and passes tests on its own.

- attempt_outcome.go — AttemptState (StateUncommitted /
  StateTransportFailure / StateServerResult), tagErr, TagErr,
  ClassifyErr. Models Java's VRpc.VRpcResult.State so the RetryingVRpc
  interceptor (later PR) can classify errors the same way as
  java-bigtable.
- vrpc.go — ctx-metadata helpers (WithVRpcMetadata, WithAttempt,
  VRpcAttempt, VRpcMethod, WithPrevAttemptErr, PrevAttemptErr). Session
  Invoke reads these from its ctx.
- session_msgtype.go — reqMsgType / respMsgType enums + classifyReq /
  classifyResp helpers. Used by the debug surface + tracer to bucket
  Session request/response types.

Part 3a/3c of the Session core sub-split (a follow-up to the original
Session core PR googleapis#20112, which is being reshaped into three thinner
PRs). Stacks on googleapis#20115 (metrics.TransportTypeName export) and googleapis#20114
(debug tag counter); each of those can merge in any order.
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
Adds the Session struct itself along with the two "surface" halves that
have no lifecycle behavior of their own — the OTel tracer and the
in-process debug counters / event ring. Also adds SessionHandle, the
per-session slot the pool checkout / picker code holds. Lifecycle
(Start / Close / readLoop / heartBeatLoop) and vRPC (Invoke) come next
in the reshaped googleapis#20112.

- session.go — Session struct + hooks + NewSession + State
  transitions (transitionTo, is/notState, signalQuiescent), vrpcResult,
  sessionErr, unavailable, afeID. Uses the existing State enum from
  session_state.go (PR googleapis#19981) — no re-declaration.
- session_debug.go — embedded sessionDebug: counters (retries, okRpcs,
  errorRpcs, msgsSent, msgsRecv), per-session event ring, latency
  histogram, cluster-id map, WithSessionLogger / WithSessionPoolName
  options, RemoteAddr / SampleUptime / RecordTransportOverhead
  accessors. Consumes metrics.TransportTypeName (googleapis#20115) and
  recordDebugTag (googleapis#20114).
- session_tracer.go — OTel sessionTracer for per-session +
  per-attempt metrics (session duration, open latency, uptime,
  transport-overhead histogram). Consumes metrics.TransportTypeName.
- picker.go — SessionHandle wrapping *Session with the per-pick
  counters (Picks, Outstanding, LastActivity) the pool needs. Its
  concrete users (SessionPool, AFE picker) come in later PRs; the
  handle type is here because Session embeds an atomic.Pointer to it.

Part 3b/3c of the Session core sub-split. Stacks on
bigtable-session-primitives (Part 3a), googleapis#20115
(metrics.TransportTypeName export), and googleapis#20114 (debug tag counter).
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
Adds the behavior half of the Session — the lifecycle state machine,
the vRPC dispatch path, and the fake-driven test suite that exercises
both. Together with the struct + surface half (bigtable-session-struct)
and the primitives (bigtable-session-primitives), this completes the
Session core.

- session_lifecycle.go — Start, ForceClose, Close, Send, readLoop,
  heartBeatLoop, handleOpenSession / handleErrorResponse /
  handleGoAway / handleClose / handleSessionParameters,
  peerInfoExtracter.
- session_vrpc.go — Invoke, buildInvokeRequest, awaitInvokeResult,
  handleVRPCResponse / handleVRPCErrorResponse, deliver,
  cancelActiveRPCs, noteRetryAttempt, releaseSlot.
- session_test.go — fakeStream / fakeDesc plus tests for
  handleOpenSession, handleVRPC*, handleGoAway, handleErrorResponse,
  Invoke, ForceClose, Close, heartBeatLoop, PeerInfo extraction,
  AfeID, Start.

Also folds in the pending gemini-code-assist review findings so this
PR merges without a follow-up:

- Fire onStart immediately after transitionTo(StateStarting) so the
  "onStart precedes onClose" invariant holds even when Send fails and
  ForceClose fires onClose.
- Nil-guard handleErrorResponse / handleSessionParameters /
  handleVRPCResponse / handleVRPCErrorResponse and the res.resp branch
  in awaitInvokeResult; drop instead of panicking in the readLoop
  goroutine.
- Retag pre-wire Send failures in Invoke as StateUncommitted (was
  StateTransportFailure) so the retry interceptor can retry
  non-idempotent ops when the frame never reached the server — Java
  parity with java-bigtable's classification.

Part 3c of 3 in the Session core sub-split. Stacks on
bigtable-session-struct (Part 3b), bigtable-session-primitives (Part
3a), googleapis#20115 (metrics.TransportTypeName), and googleapis#20114 (debug tag counter).
Address gemini-code-assist review on googleapis#20114:

- Store debugTagCounter in an atomic.Value so the register-once write
  and every-emission reads don't race on the two-word interface value.
- Rename bumpDebugTagCountLocked -> bumpDebugTagCount; it handles its
  own locking, so the "Locked" suffix (which conventionally means the
  caller holds the lock) was misleading.
- Release DebugTags()'s RLock before sorting the local snapshot slice.
  The sort touches no shared state and there's no reason to hold the
  read lock across it.
@sushanb sushanb changed the title [2/5] feat(bigtable): add debug tag counter (recordDebugTag / assertDebugTag) feat(bigtable): add debug tag counter (recordDebugTag / assertDebugTag) Jul 9, 2026
sushanb added 2 commits July 9, 2026 17:41
Insert a blank line between the file-level how-to-use block and
`package internal` so golint doesn't misread the block as the package
comment and complain that it should be of the form "Package
internal ...". The block documents the file, not the package — the
detached form is the idiomatic fix.
Cut redundant prose across the file, function, and variable comments —
the essential "why" and Java-parity notes stay, but the how-to-use
material collapses to an entry-point list and three rules. Net -74
lines of comment weight; no behavior change.
// java-bigtable); Go identifiers are camelCase. Grep either form to
// jump between the definition and its emission sites.
const (
// Session-lifecycle observations.

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.

should we have the same list as java?

SessionPoolImpl.java

  • session_pool_drained_future_failed (ERROR) — SessionPoolImpl.java:347
  • session_pool_no_budget (WARN) — SessionPoolImpl.java:405
  • watchdog_close_session (WARN) — SessionPoolImpl.java:957

SessionImpl.java

  • session_close_no_reason (WARN) — SessionImpl.java:385 and SessionImpl.java:783
  • session_closed_discard_vrpc_response (WARN) — SessionImpl.java:574 and SessionImpl.java:644
  • session_go_away_ignored (WARN) — SessionImpl.java:692
  • session_unknown_response (WARN) — SessionImpl.java:720
  • session_abnormal_close (WARN) — SessionImpl.java:740

And I'll port the ones that's not in java over.

Comment thread bigtable/internal/transport/debug_tracer.go
@sushanb
sushanb merged commit 3c97590 into googleapis:main Jul 9, 2026
19 checks passed
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
…type)

Adds the standalone types that the Session struct and its lifecycle /
vRPC / debug halves all depend on. Each file is self-contained (no
cross-references) so this PR compiles and passes tests on its own.

- attempt_outcome.go — AttemptState (StateUncommitted /
  StateTransportFailure / StateServerResult), tagErr, TagErr,
  ClassifyErr. Models Java's VRpc.VRpcResult.State so the RetryingVRpc
  interceptor (later PR) can classify errors the same way as
  java-bigtable.
- vrpc.go — ctx-metadata helpers (WithVRpcMetadata, WithAttempt,
  VRpcAttempt, VRpcMethod, WithPrevAttemptErr, PrevAttemptErr). Session
  Invoke reads these from its ctx.
- session_msgtype.go — reqMsgType / respMsgType enums + classifyReq /
  classifyResp helpers. Used by the debug surface + tracer to bucket
  Session request/response types.

Part 3a/3c of the Session core sub-split (a follow-up to the original
Session core PR googleapis#20112, which is being reshaped into three thinner
PRs). Stacks on googleapis#20115 (metrics.TransportTypeName export) and googleapis#20114
(debug tag counter); each of those can merge in any order.
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
…type)

Adds the standalone types that the Session struct and its lifecycle /
vRPC / debug halves all depend on. Each file is self-contained (no
cross-references) so this PR compiles and passes tests on its own.

- attempt_outcome.go — AttemptState (StateUncommitted /
  StateTransportFailure / StateServerResult), tagErr, TagErr,
  ClassifyErr. Models Java's VRpc.VRpcResult.State so the RetryingVRpc
  interceptor (later PR) can classify errors the same way as
  java-bigtable.
- vrpc.go — ctx-metadata helpers (WithVRpcMetadata, WithAttempt,
  VRpcAttempt, VRpcMethod, WithPrevAttemptErr, PrevAttemptErr). Session
  Invoke reads these from its ctx.
- session_msgtype.go — reqMsgType / respMsgType enums + classifyReq /
  classifyResp helpers. Used by the debug surface + tracer to bucket
  Session request/response types.

Part 3a/3c of the Session core sub-split (a follow-up to the original
Session core PR googleapis#20112, which is being reshaped into three thinner
PRs). Stacks on googleapis#20115 (metrics.TransportTypeName export) and googleapis#20114
(debug tag counter); each of those can merge in any order.
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
Adds the Session struct itself along with the two "surface" halves that
have no lifecycle behavior of their own — the OTel tracer and the
in-process debug counters / event ring. Also adds SessionHandle, the
per-session slot the pool checkout / picker code holds. Lifecycle
(Start / Close / readLoop / heartBeatLoop) and vRPC (Invoke) come next
in the reshaped googleapis#20112.

- session.go — Session struct + hooks + NewSession + State
  transitions (transitionTo, is/notState, signalQuiescent), vrpcResult,
  sessionErr, unavailable, afeID. Uses the existing State enum from
  session_state.go (PR googleapis#19981) — no re-declaration.
- session_debug.go — embedded sessionDebug: counters (retries, okRpcs,
  errorRpcs, msgsSent, msgsRecv), per-session event ring, latency
  histogram, cluster-id map, WithSessionLogger / WithSessionPoolName
  options, RemoteAddr / SampleUptime / RecordTransportOverhead
  accessors. Consumes metrics.TransportTypeName (googleapis#20115) and
  recordDebugTag (googleapis#20114).
- session_tracer.go — OTel sessionTracer for per-session +
  per-attempt metrics (session duration, open latency, uptime,
  transport-overhead histogram). Consumes metrics.TransportTypeName.
- picker.go — SessionHandle wrapping *Session with the per-pick
  counters (Picks, Outstanding, LastActivity) the pool needs. Its
  concrete users (SessionPool, AFE picker) come in later PRs; the
  handle type is here because Session embeds an atomic.Pointer to it.

Part 3b/3c of the Session core sub-split. Stacks on
bigtable-session-primitives (Part 3a), googleapis#20115
(metrics.TransportTypeName export), and googleapis#20114 (debug tag counter).
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
…type)

Adds the standalone types that the Session struct and its lifecycle /
vRPC / debug halves all depend on. Each file is self-contained (no
cross-references) so this PR compiles and passes tests on its own.

- attempt_outcome.go — AttemptState (StateUncommitted /
  StateTransportFailure / StateServerResult), tagErr, TagErr,
  ClassifyErr. Models Java's VRpc.VRpcResult.State so the RetryingVRpc
  interceptor (later PR) can classify errors the same way as
  java-bigtable.
- vrpc.go — ctx-metadata helpers (WithVRpcMetadata, WithAttempt,
  VRpcAttempt, VRpcMethod, WithPrevAttemptErr, PrevAttemptErr). Session
  Invoke reads these from its ctx.
- session_msgtype.go — reqMsgType / respMsgType enums + classifyReq /
  classifyResp helpers. Used by the debug surface + tracer to bucket
  Session request/response types.

Part 3a/3c of the Session core sub-split (a follow-up to the original
Session core PR googleapis#20112, which is being reshaped into three thinner
PRs). Stacks on googleapis#20115 (metrics.TransportTypeName export) and googleapis#20114
(debug tag counter); each of those can merge in any order.
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
Adds the Session struct itself along with the two "surface" halves that
have no lifecycle behavior of their own — the OTel tracer and the
in-process debug counters / event ring. Also adds SessionHandle, the
per-session slot the pool checkout / picker code holds. Lifecycle
(Start / Close / readLoop / heartBeatLoop) and vRPC (Invoke) come next
in the reshaped googleapis#20112.

- session.go — Session struct + hooks + NewSession + State
  transitions (transitionTo, is/notState, signalQuiescent), vrpcResult,
  sessionErr, unavailable, afeID. Uses the existing State enum from
  session_state.go (PR googleapis#19981) — no re-declaration.
- session_debug.go — embedded sessionDebug: counters (retries, okRpcs,
  errorRpcs, msgsSent, msgsRecv), per-session event ring, latency
  histogram, cluster-id map, WithSessionLogger / WithSessionPoolName
  options, RemoteAddr / SampleUptime / RecordTransportOverhead
  accessors. Consumes metrics.TransportTypeName (googleapis#20115) and
  recordDebugTag (googleapis#20114).
- session_tracer.go — OTel sessionTracer for per-session +
  per-attempt metrics (session duration, open latency, uptime,
  transport-overhead histogram). Consumes metrics.TransportTypeName.
- picker.go — SessionHandle wrapping *Session with the per-pick
  counters (Picks, Outstanding, LastActivity) the pool needs. Its
  concrete users (SessionPool, AFE picker) come in later PRs; the
  handle type is here because Session embeds an atomic.Pointer to it.

Part 3b/3c of the Session core sub-split. Stacks on
bigtable-session-primitives (Part 3a), googleapis#20115
(metrics.TransportTypeName export), and googleapis#20114 (debug tag counter).
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
Adds the behavior half of the Session — the lifecycle state machine,
the vRPC dispatch path, and the fake-driven test suite that exercises
both. Together with the struct + surface half (bigtable-session-struct)
and the primitives (bigtable-session-primitives), this completes the
Session core.

- session_lifecycle.go — Start, ForceClose, Close, Send, readLoop,
  heartBeatLoop, handleOpenSession / handleErrorResponse /
  handleGoAway / handleClose / handleSessionParameters,
  peerInfoExtracter.
- session_vrpc.go — Invoke, buildInvokeRequest, awaitInvokeResult,
  handleVRPCResponse / handleVRPCErrorResponse, deliver,
  cancelActiveRPCs, noteRetryAttempt, releaseSlot.
- session_test.go — fakeStream / fakeDesc plus tests for
  handleOpenSession, handleVRPC*, handleGoAway, handleErrorResponse,
  Invoke, ForceClose, Close, heartBeatLoop, PeerInfo extraction,
  AfeID, Start.

Also folds in the pending gemini-code-assist review findings so this
PR merges without a follow-up:

- Fire onStart immediately after transitionTo(StateStarting) so the
  "onStart precedes onClose" invariant holds even when Send fails and
  ForceClose fires onClose.
- Nil-guard handleErrorResponse / handleSessionParameters /
  handleVRPCResponse / handleVRPCErrorResponse and the res.resp branch
  in awaitInvokeResult; drop instead of panicking in the readLoop
  goroutine.
- Retag pre-wire Send failures in Invoke as StateUncommitted (was
  StateTransportFailure) so the retry interceptor can retry
  non-idempotent ops when the frame never reached the server — Java
  parity with java-bigtable's classification.

Part 3c of 3 in the Session core sub-split. Stacks on
bigtable-session-struct (Part 3b), bigtable-session-primitives (Part
3a), googleapis#20115 (metrics.TransportTypeName), and googleapis#20114 (debug tag counter).
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 9, 2026
…type)

Adds the standalone types that the Session struct and its lifecycle /
vRPC / debug halves all depend on. Each file is self-contained (no
cross-references) so this PR compiles and passes tests on its own.

- attempt_outcome.go — AttemptState (StateUncommitted /
  StateTransportFailure / StateServerResult), tagErr, TagErr,
  ClassifyErr. Models Java's VRpc.VRpcResult.State so the RetryingVRpc
  interceptor (later PR) can classify errors the same way as
  java-bigtable.
- vrpc.go — ctx-metadata helpers (WithVRpcMetadata, WithAttempt,
  VRpcAttempt, VRpcMethod, WithPrevAttemptErr, PrevAttemptErr). Session
  Invoke reads these from its ctx.
- session_msgtype.go — reqMsgType / respMsgType enums + classifyReq /
  classifyResp helpers. Used by the debug surface + tracer to bucket
  Session request/response types.

Part 3a/3c of the Session core sub-split (a follow-up to the original
Session core PR googleapis#20112, which is being reshaped into three thinner
PRs). Stacks on googleapis#20115 (metrics.TransportTypeName export) and googleapis#20114
(debug tag counter); each of those can merge in any order.
sushanb added a commit that referenced this pull request Jul 10, 2026
…type) (#20116)

## Summary

Adds the standalone types that the Session struct and its lifecycle /
vRPC / debug halves all depend on. Each file is self-contained (no
cross-references) so this PR compiles and passes tests on its own.

- **`attempt_outcome.go`** — `AttemptState` (`StateUncommitted` /
`StateTransportFailure` / `StateServerResult`), `tagErr`, `TagErr`,
`ClassifyErr`. Models Java's `VRpc.VRpcResult.State` so the
`RetryingVRpc` interceptor (later PR) can classify errors the same way
as java-bigtable.
- **`vrpc.go`** — ctx-metadata helpers (`WithVRpcMetadata`,
`WithAttempt`, `VRpcAttempt`, `VRpcMethod`, `WithPrevAttemptErr`,
`PrevAttemptErr`). `Session.Invoke` reads these from its ctx.
- **`session_msgtype.go`** — `reqMsgType` / `respMsgType` enums +
`classifyReq` / `classifyResp` helpers. Used by the debug surface +
tracer to bucket Session request/response types.

**Part 3a of 3 in the Session core sub-split** (a follow-up to the
original Session core PR #20112, which is being reshaped into three
thinner PRs). Stacks on #20115 (`metrics.TransportTypeName` export) and
#20114 (debug tag counter); each of those can merge in any order.
Sub-split order:

1. **3a — this PR:** Session primitives (~337 LOC).
2. **3b — TBD:** Session struct + tracer + debug surface + picker (~1.1k
LOC).
3. **3c — reshaped #20112:** Session lifecycle + vRPC + tests (~2k LOC).

## Test plan

- [x] `go build ./bigtable/...`
- [x] `go test ./bigtable/internal/transport/ -count=1 -short` — passes
(4.0s)
- [x] `gofmt -l bigtable/internal/transport/` — clean
- [ ] CI: presubmit
sushanb added a commit to sushanb/google-cloud-go that referenced this pull request Jul 10, 2026
Adds the Session struct itself along with the two "surface" halves that
have no lifecycle behavior of their own — the OTel tracer and the
in-process debug counters / event ring. Also adds SessionHandle, the
per-session slot the pool checkout / picker code holds. Lifecycle
(Start / Close / readLoop / heartBeatLoop) and vRPC (Invoke) come next
in the reshaped googleapis#20112.

- session.go — Session struct + hooks + NewSession + State
  transitions (transitionTo, is/notState, signalQuiescent), vrpcResult,
  sessionErr, unavailable, afeID. Uses the existing State enum from
  session_state.go (PR googleapis#19981) — no re-declaration.
- session_debug.go — embedded sessionDebug: counters (retries, okRpcs,
  errorRpcs, msgsSent, msgsRecv), per-session event ring, latency
  histogram, cluster-id map, WithSessionLogger / WithSessionPoolName
  options, RemoteAddr / SampleUptime / RecordTransportOverhead
  accessors. Consumes metrics.TransportTypeName (googleapis#20115) and
  recordDebugTag (googleapis#20114).
- session_tracer.go — OTel sessionTracer for per-session +
  per-attempt metrics (session duration, open latency, uptime,
  transport-overhead histogram). Consumes metrics.TransportTypeName.
- picker.go — SessionHandle wrapping *Session with the per-pick
  counters (Picks, Outstanding, LastActivity) the pool needs. Its
  concrete users (SessionPool, AFE picker) come in later PRs; the
  handle type is here because Session embeds an atomic.Pointer to it.

Part 3b/3c of the Session core sub-split. Stacks on
bigtable-session-primitives (Part 3a), googleapis#20115
(metrics.TransportTypeName export), and googleapis#20114 (debug tag counter).
hongalex pushed a commit that referenced this pull request Jul 23, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.51.0](bigtable/v1.50.0...bigtable/v1.51.0)
(2026-07-23)


### Features

* **bigtable:** Add ChainInterceptors and RetryingVRpc for vRPC pipeline
([#20185](#20185))
([c7a832a](c7a832a))
* **bigtable:** Add ClientConfigurationManager
([#19986](#19986))
([3a8f927](3a8f927))
* **bigtable:** Add debug tag counter (recordDebugTag / assertDebugTag)
([#20114](#20114))
([3c97590](3c97590))
* **bigtable:** Add lazyPool helper for on-demand session pool opening
([#20182](#20182))
([f6ae3fb](f6ae3fb))
* **bigtable:** Add PeakEwma continuous time-decay latency tracker
([#20187](#20187))
([9d124ef](9d124ef))
* **bigtable:** Add PoolSizer for server-driven session pool capacity
([#20189](#20189))
([57ebbeb](57ebbeb))
* **bigtable:** Add session package with SessionClient + SessionTableAPI
interfaces
([#20180](#20180))
([4b82fd2](4b82fd2))
* **bigtable:** Add Session primitives (AttemptOutcome, vRPC ctx,
msgtype)
([#20116](#20116))
([e1011e2](e1011e2))
* **bigtable:** Add Session state enum
([#19981](#19981))
([0748972](0748972))
* **bigtable:** Add SessionThrottler / AdaptiveSessionThrottler for
OpenSession pacing
([#20184](#20184))
([02e3c6d](02e3c6d))
* **bigtable:** Add SessionThrottler / AdaptiveSessionThrottler for
OpenSession pacing
([#20184](#20184))
([29be83e](29be83e))
* **bigtable:** Add sessionTracer for per-Session lifecycle + vRPC
metrics
([#20190](#20190))
([a466345](a466345))
* **bigtable:** Enable new auth library and JWT for instance admin
client
([#20013](#20013))
([21c4a44](21c4a44))
* **bigtable:** Modularize channel priming behind a ChannelPrimer
interface
([#20027](#20027))
([5214ab7](5214ab7))
* **bigtable:** Modularize Direct Access compatibility check
([#19987](#19987))
([a25e93d](a25e93d))
* **o11y:** Regenerate clients for LRO tracing
([#20107](#20107))
([779074e](779074e))


### Bug Fixes

* **bigtable:** Default cluster/zone in toOtelMetricAttrs to avoid
Monitoring reject
([#20178](#20178))
([14493f4](14493f4))
* **bigtable:** Eliminate stats-handler MD race in internal/metrics
tracer
([#20158](#20158))
([c387066](c387066))

---
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

api: bigtable Issues related to the Bigtable API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants