Repository navigation
fix(bigtable): handle empty SessionPoolConfiguration in SessionPoolImpl and PoolSizer - #14912
Conversation
There was a problem hiding this comment.
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.
…ration is disabled
|
|
||
| poolStats.startingCount--; | ||
| poolStats.readyCount++; | ||
| if (inExpectedCount) { |
There was a problem hiding this comment.
do we need to set this to false after incrementing readyCount?
There was a problem hiding this comment.
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) { |
| @GuardedBy("poolLock") | ||
| private void maybeScheduleCreateSessionRetry() { | ||
| if (retryCreateSessionFuture != null) { | ||
| if (retryCreateSessionFuture != null || budget.getMaxConcurrentRequest() <= 0) { |
There was a problem hiding this comment.
would it be better to set a sessionDisabled flag? instead of checking specific params?
There was a problem hiding this comment.
good idea, centralized the logic
…poolSizer.isDisabled()
…rk disabled volatile
|
/gemini review |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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.
| retryCreateSessionFuture.cancel(); | |
| retryCreateSessionFuture.cancel(false); |
| @SuppressWarnings("GuardedBy") | ||
| private void cancel(Status status, boolean onlyCancelPendingCall) { | ||
| if (deadlineMonitor != null) { | ||
| deadlineMonitor.cancel(); |
There was a problem hiding this comment.
|
|
||
| void cancelWithResult(VRpcResult result) { | ||
| if (deadlineMonitor != null) { | ||
| deadlineMonitor.cancel(); |
There was a problem hiding this comment.
Summary
When
session_load == 0across all scopes,ClientConfigurationManager.normalizeConfigclearssession_configuration, resulting in an emptySessionPoolConfiguration.getDefaultInstance().This change updates
PoolSizerandSessionPoolImplto handle an emptySessionPoolConfigurationcleanly:PoolSizer:pendingVRpcsPerSession > 0ingetScaleDelta()to prevent divide-by-zero (+Infinity->Integer.MAX_VALUEandintoverflow wheninUseCount >= 1).handleGoAwayandhandleSessionClosefromgetScaleDelta() >= 0togetScaleDelta() > 0(sinceonSessionClosing/onSessionClosedalready decrementsexpectedCapacityprior to consultingPoolSizer).SessionPoolImpl&SessionList:maybeScheduleCreateSessionRetry()withbudget.getMaxConcurrentRequest() <= 0so it does not spin on a 1ms retry timer whenbudget == 0.SessionHandle.onSessionClosing()idempotent with respect toexpectedCapacity.newConfigisSessionPoolConfiguration.getDefaultInstance(), cancelsretryCreateSessionFutureand gracefully closes all sessions (CLOSE_SESSION_REASON_DOWNSIZE); whennewConfigis non-empty andpoolState == PoolState.STARTED, scales back up via the pre-start loop.