Skip to content

fix(bigtable): handle empty SessionPoolConfiguration in SessionPoolImpl and PoolSizer - #14912

Merged
igorbernstein2 merged 7 commits into
mainfrom
fix-session-pool-disabled-config
Nov 10, 2026
Merged

igorbernstein2 merged 7 commits into
mainfrom
fix-session-pool-disabled-config

Conversation

@igorbernstein2

Copy link
Copy Markdown
Contributor

Summary

When session_load == 0 across all scopes, ClientConfigurationManager.normalizeConfig clears session_configuration, resulting in an empty SessionPoolConfiguration.getDefaultInstance().

This change updates PoolSizer and SessionPoolImpl to handle an empty SessionPoolConfiguration cleanly:

  • PoolSizer:
    • Guards pendingVRpcsPerSession > 0 in getScaleDelta() to prevent divide-by-zero (+Infinity -> Integer.MAX_VALUE and int overflow when inUseCount >= 1).
    • Updates handleGoAway and handleSessionClose from getScaleDelta() >= 0 to getScaleDelta() > 0 (since onSessionClosing / onSessionClosed already decrements expectedCapacity prior to consulting PoolSizer).
  • SessionPoolImpl & SessionList:
    • Guards maybeScheduleCreateSessionRetry() with budget.getMaxConcurrentRequest() <= 0 so it does not spin on a 1ms retry timer when budget == 0.
    • Makes SessionHandle.onSessionClosing() idempotent with respect to expectedCapacity.
    • In the config listener, when newConfig is SessionPoolConfiguration.getDefaultInstance(), cancels retryCreateSessionFuture and gracefully closes all sessions (CLOSE_SESSION_REASON_DOWNSIZE); when newConfig is non-empty and poolState == PoolState.STARTED, scales back up via the pre-start loop.

@igorbernstein2
igorbernstein2 requested review from a team as code owners November 3, 2026 18:36

@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 adds robust handling for empty or disabled session pool configurations in the Google Cloud Bigtable client. Key changes include preventing division-by-zero errors in PoolSizer when pendingVRpcsPerSession is zero, updating SessionPoolImpl to properly cancel retry futures and close active sessions when the configuration is reset to default, and adding corresponding unit tests. The review feedback correctly identifies a compilation error in SessionPoolImpl.java where Future.cancel() is called without its required boolean argument, and suggests using cancel(false) instead.


poolStats.startingCount--;
poolStats.readyCount++;
if (inExpectedCount) {

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.

do we need to set this to false after incrementing readyCount?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, that field name is misleading. I renamed it to closing

inUseSessions.remove(this);

if (session.getState() == SessionState.READY) {
if (inExpectedCount && session.getState() == SessionState.READY) {

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.

same question here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same :)

@GuardedBy("poolLock")
private void maybeScheduleCreateSessionRetry() {
if (retryCreateSessionFuture != null) {
if (retryCreateSessionFuture != null || budget.getMaxConcurrentRequest() <= 0) {

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.

would it be better to set a sessionDisabled flag? instead of checking specific params?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea, centralized the logic

@mutianf

mutianf commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

/gemini review

@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 support for dynamically disabling the session pool configuration, gracefully handling transitions to an empty or disabled state by closing active sessions, cancelling pending RPCs, and rejecting new calls. It also addresses potential race conditions during session startup and closing by replacing the inExpectedCount flag with a closing state, and fixes potential division-by-zero errors in the pool sizer. However, there are critical compilation errors in SessionPoolImpl.java where cancel() is called without the required boolean argument on Future objects (retryCreateSessionFuture and deadlineMonitor). These must be updated to cancel(false) to resolve the build failures.

picker.updateConfig(newConfig);
if (poolSizer.isDisabled()) {
if (retryCreateSessionFuture != null) {
retryCreateSessionFuture.cancel();

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.

critical

Calling cancel() with no arguments on retryCreateSessionFuture (which is a ScheduledFuture or Future) will cause a compilation error in Java. The Future.cancel method requires a boolean parameter indicating whether to interrupt the running thread. Please use cancel(false) instead.

Suggested change
retryCreateSessionFuture.cancel();
retryCreateSessionFuture.cancel(false);

@SuppressWarnings("GuardedBy")
private void cancel(Status status, boolean onlyCancelPendingCall) {
if (deadlineMonitor != null) {
deadlineMonitor.cancel();

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.

critical

Calling cancel() with no arguments on deadlineMonitor (which is a ScheduledFuture or Future) will cause a compilation error in Java. The Future.cancel method requires a boolean parameter. Please use cancel(false) instead.

Suggested change
deadlineMonitor.cancel();
deadlineMonitor.cancel(false);


void cancelWithResult(VRpcResult result) {
if (deadlineMonitor != null) {
deadlineMonitor.cancel();

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.

critical

Calling cancel() with no arguments on deadlineMonitor (which is a ScheduledFuture or Future) will cause a compilation error in Java. The Future.cancel method requires a boolean parameter. Please use cancel(false) instead.

Suggested change
deadlineMonitor.cancel();
deadlineMonitor.cancel(false);

@igorbernstein2
igorbernstein2 enabled auto-merge (squash) November 10, 2026 20:40
@igorbernstein2
igorbernstein2 merged commit cc7b235 into main Nov 10, 2026
208 checks passed
@igorbernstein2
igorbernstein2 deleted the fix-session-pool-disabled-config branch November 10, 2026 21:02
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