Skip to content

Clear post-authentication hooks properly with pool.destroy - #4749

Merged
atakavci merged 6 commits into
redis:masterfrom
atakavci:ali/fixAuthHooks
Sep 29, 2026
Merged

atakavci merged 6 commits into
redis:masterfrom
atakavci:ali/fixAuthHooks

Conversation

@atakavci

@atakavci atakavci commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

ConnectionPool registers a post-authentication hook on its AuthXManager but never managed to remove it, because this::postAuthentication yields a new object on every evaluation and the list removal never matched. Stale hooks on closed pools then threw from evict() into the token manager's renewal cycle. On top of that, ConnectionPool.close() stopped the manager unconditionally even though the application created it and may share it. This PR fixes the unregistration and leaves the manager's lifecycle to its creator.

Key Decisions & Assumptions

  • The AuthXManager is created by the application and passed in via JedisClientConfig, so Jedis does not stop it, mirroring how the config itself is owned. Reference counting and restart-on-reuse were considered and rejected as hidden lifecycle magic.
  • Unregistration lives in destroy(), which every teardown path (close(), cluster refresh, sentinel failover, multi-db forceDisconnect) already goes through. TrackingConnectionPool no longer needs its own close() override.
  • The hook list becomes a CopyOnWriteArrayList since pool threads mutate it while the renewal thread iterates.

Behavioral / Conceptual Changes

  • Closing a standalone or sentinel client no longer stops the AuthXManager. Cluster and multi-db clients never did, so all clients are now consistent. Applications must call authXManager.stop() after closing the last client that uses it.
  • Sentinel master failover no longer kills token renewal for the new master pool, and closing one of several clients sharing a manager no longer breaks the others.
  • Destroyed pools are removed from the manager, so repeated pool rotation no longer accumulates hooks or fails the renewal cycle. A renewal racing with destroy() is skipped instead of throwing.

Testing

New unit tests verify hooks are registered once and removed on destroy or close, that only the closed pool is unregistered when a manager is shared, that a sentinel +switch-master leaves only the new master pool registered, and that a multi-db forceDisconnect plus recreation registers exactly once. None require a running Redis. The EntraID integration tests were not run.

Notes

  • Behavior change is recorded in the 8.1.0 release notes and the lifecycle is documented in docs/advanced-usage.md.

Note

Medium Risk
Behavior change for apps that relied on client close() to stop AuthXManager; fixes auth renewal bugs on shared managers and failover but requires explicit authXManager.stop().

Overview
Fixes token auth (AuthXManager) hook cleanup and lifecycle so shared managers and pool rotation (Sentinel failover, multi-db reconnect) stay reliable.

ConnectionPool no longer stops AuthXManager on close() — lifecycle matches application ownership (like JedisClientConfig). Call authXManager.stop() after the last client using it closes, or renewal threads keep running.

Destroyed/closed pools unregister their post-authentication hook in destroy() via a stable hook reference (fixes removal that failed with this::postAuthentication). AuthXManager uses CopyOnWriteArrayList for hooks. Closed pools skip or swallow post-auth evict() races so renewal does not fail for other pools. TrackingConnectionPool drops a redundant close() override.

Docs: 8.1.0 behavior change and advanced-usage lifecycle note. New unit tests cover shared managers, Sentinel failover, and forceDisconnect/recreate.

Reviewed by Cursor Bugbot for commit 274858a. Bugbot is set up for automated code reviews on this repo. Configure here.

@atakavci
atakavci requested a review from ggivo September 25, 2026 12:18
@atakavci atakavci self-assigned this Sep 25, 2026
@atakavci atakavci added the bug label Sep 25, 2026
@atakavci
atakavci marked this pull request as ready for review September 25, 2026 12:26

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 72d03e9. Configure here.

Comment thread src/main/java/redis/clients/jedis/ConnectionPool.java

@ggivo ggivo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@atakavci
atakavci merged commit ad150f4 into redis:master Sep 29, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants