feat(bigtable): add session package with SessionClient + SessionTableAPI interfaces - #20180
Conversation
…API interfaces
Introduces bigtable/internal/session, an internal package that holds the
vRPC-over-session data-plane API surface. This change lands interfaces
only; implementations follow in subsequent PRs.
SessionTableAPI is the per-resource, proto-native surface (ReadRow /
MutateRow / Close) that takes and returns *SessionReadRow{Request,
Response} and *SessionMutateRow{Request,Response} instead of
bigtable.Row.
SessionClient owns the underlying gRPC channel pool and vends per-
resource SessionTableAPI instances for standard tables, authorized
views, and materialized views. It exposes the OTel MeterProvider used
for metrics and an AddSessionLoadListener hook that mixed-mode callers
can wire to the server-driven session-load ratio.
Landing the interfaces first keeps each follow-up PR small enough to
review: the lazy-pool + table implementation, the client, and the
per-resource pool wiring can each be evaluated against a stable API.
There was a problem hiding this comment.
Code Review
This pull request introduces the session package, defining the SessionTableAPI and SessionClient interfaces to support a proto-native alternative to the classic gRPC TableAPI. The feedback suggests documenting the strict ordering requirement for closing SessionTableAPI instances before closing the SessionClient to ensure a clean shutdown and prevent resource leaks.
| // Close closes the underlying channel pool. SessionTableAPI | ||
| // instances previously vended become unusable. | ||
| Close() error |
There was a problem hiding this comment.
Since SessionClient does not cache or track the vended SessionTableAPI instances, callers must ensure that all vended SessionTableAPI instances are closed before closing the SessionClient. If the SessionClient is closed first, the underlying gRPC channel pool will be shut down, which will prevent the SessionTableAPI instances from performing a clean shutdown (such as sending session deletion RPCs to the server) when they are subsequently closed.
It is highly recommended to document this strict ordering requirement in the Close method's documentation to prevent resource leaks or clean-up errors in client applications.
// Close closes the underlying channel pool. SessionTableAPI
// instances previously vended become unusable. Callers must ensure
// all vended SessionTableAPI instances are closed before closing the
// SessionClient to allow them to perform a clean shutdown (e.g.,
// deleting sessions on the server) while the channel pool is still active.
Close() errorThere was a problem hiding this comment.
Addressed in ab526a8 — expanded the SessionClient.Close doc to spell out the ordering requirement (close vended SessionTableAPI instances first; the shared channel pool going away prevents cleanup RPCs like session deletion).
Callers should close every vended SessionTableAPI before closing the SessionClient — closing the client tears down the shared channel pool, so any SessionTableAPI still open at that point can no longer issue cleanup RPCs (e.g., session deletion). Addresses gemini-code-assist review comment on googleapis#20180.
Rename session.SessionClient → session.Client and session.SessionTableAPI → session.TableAPI to satisfy golint's stutter check. Doc comments referencing the old names updated in the same file. No consumers yet, so no cross-file changes. Fixes CI vet failure on PR googleapis#20180.
🤖 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>
Summary
Introduces
bigtable/internal/session, an internal package that establishes the vRPC-over-session data-plane API surface for the Bigtable Go client. This PR ships interfaces only — the implementation (lazy per-resource read/write pools, theSessionClientthat owns the channel pool, and the per-resourcesessionTable) lands in subsequent, individually reviewable PRs.Two interfaces:
SessionTableAPI— per-resource, proto-native data-plane surface.ReadRow/MutateRowtake and return*SessionReadRow{Request,Response}and*SessionMutateRow{Request,Response}(frombigtable/apiv2/bigtablepb) instead ofbigtable.Row.Closereleases the resource's read + write pools without touching the shared channel pool.SessionClient— owns the underlying gRPC channel pool + stub and vends per-resourceSessionTableAPIinstances for standard tables, authorized views, and materialized views (read-only). Exposes the OTelMeterProviderused for metrics and anAddSessionLoadListenerhook that mixed-mode callers can wire to the server-driven session-load ratio (0.0 = classic-only, 1.0 = session-only).Why split it out first
The follow-up PRs (lazy-pool +
sessionTable,sessionClientconstruction, per-resource pool wiring) each depend on this shape. Landing the API first keeps each subsequent PR small enough to review against a stable target and lets consumers (the top-levelbigtablepackage's TableShim + Diverter, or standaloneSessionClientusers) type-check against a single import path.Everything in this file is internal (
bigtable/internal/session/...) — nothing is exposed on the publicbigtablepackage API.Test plan
go build ./bigtable/internal/session/go vet ./bigtable/internal/session/