Skip to content

fix(bigtable): stop SessionPoolImpl watchdog when sessions finish draining - #14977

Open
mutianf wants to merge 1 commit into
googleapis:mainfrom
mutianf:fix-session-pool-watchdog-leak
Open

mutianf wants to merge 1 commit into
googleapis:mainfrom
mutianf:fix-session-pool-watchdog-leak

Conversation

@mutianf

@mutianf mutianf commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

SessionPoolImpl.close() previously left the pool's Watchdog running until awaitTerminated() was called. Callers that close a pool without calling awaitTerminated() (such as TableBase.close() when an idle table is evicted from compat.Util.createSessionMap) leaked the self-rescheduling watchdog on the client's shared HashedWheelTimer, retaining the closed SessionPoolImpl in memory.

Close the watchdog as soon as all sessions drain after close() (immediately if the pool is empty, or in onSessionClose() when the last session terminates), and guard onSessionGoAway() against creating replacement sessions after the pool is closed.

…ining

SessionPoolImpl.close() previously left the watchdog running until awaitTerminated() was called. Callers that close a pool without calling awaitTerminated() (such as TableBase.close() when an idle table is evicted from compat.Util.createSessionMap) leaked the self-rescheduling watchdog on the client's shared HashedWheelTimer, retaining the closed SessionPoolImpl in memory.

Close the watchdog as soon as all sessions drain after close() (immediately if the pool is empty, or in onSessionClose when the last session terminates), and guard onSessionGoAway against creating replacement sessions after the pool is closed.
@mutianf
mutianf requested review from a team as code owners November 12, 2026 03:25

@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 ensures that the watchdog timer is closed when the session pool is closed and all sessions have drained, preventing potential timer leaks when callers only invoke close() without calling awaitTerminated(). A new test is added to verify this behavior. The review feedback suggests using System.nanoTime() instead of System.currentTimeMillis() in the test's wait loop to ensure monotonic time measurements and avoid sensitivity to system clock adjustments.

Comment on lines +361 to +364
long deadlineMs = System.currentTimeMillis() + 10_000;
while (!sessionPool.watchdog.isClosed() && System.currentTimeMillis() < deadlineMs) {
Thread.sleep(10);
}

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.

medium

Using System.currentTimeMillis() to measure deadlines or elapsed time is sensitive to system clock adjustments (such as NTP updates). It is safer and more robust to use System.nanoTime() for monotonic time measurements in test wait loops.

Suggested change
long deadlineMs = System.currentTimeMillis() + 10_000;
while (!sessionPool.watchdog.isClosed() && System.currentTimeMillis() < deadlineMs) {
Thread.sleep(10);
}
long deadlineNano = System.nanoTime() + TimeUnit.SECONDS.toNanos(10);
while (!sessionPool.watchdog.isClosed() && System.nanoTime() < deadlineNano) {
Thread.sleep(10);
}

This branch has not been deployed

No deployments
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.

1 participant