Skip to content

[maintenance events] Support maintenance PUSH notification #4473

Open
ggivo wants to merge 77 commits into
masterfrom
feature/hu-notifications-rebased-wo-generic-push-listeners
Open

[maintenance events] Support maintenance PUSH notification #4473
ggivo wants to merge 77 commits into
masterfrom
feature/hu-notifications-rebased-wo-generic-push-listeners

Conversation

@ggivo
Copy link
Copy Markdown
Collaborator

@ggivo ggivo commented Mar 25, 2026

Description

This PR enhances Jedis and UnifiedJedis with improved support for RESP3 push messages and introduces a configurable option for relaxed timeout behavior.

These changes are part of a broader effort to support more robust and controlled upgrade and maintenance scenarios. Specifically, they lay the groundwork for:

  • Temporarily relaxing timeouts during planned maintenance windows.
  • Gracefully re-binding pooled connections to updated endpoints without disrupting active operations.

This PR aims to provide support for reading arbitrary PUSH notifications (such as maintenance events) and serve as an initial commit for introducing support for timeout relaxation on miantenace events

Backround

In the current state of the client:

  • Jedis supports only known Push notifications like invalidate. Push notifications are supported using dedicated client-side caching (CSC) connection (CacheConnection)
  • This leads to runtime errors if CLIENT TRACKING ON is enabled in a context other than CSC, or if other RESP3 push events are received.

Changes Introduced

  • Added support for processing and discarding all RESP3 push messages, preventing errors in non-CSC scenarios.
  • Pub/Sub push messages are still handled as before and propagated to the client for backward compatibility.
  • Added a configurable option to enable relaxed timeout behavior, intended for usage during maintenance events or when expecting slow responses from the server.

Note

Medium Risk
Changes core connection/pooling behavior by altering socket timeout handling during blocking calls and disposing/rebinding pooled connections on server push events; regressions could surface as unexpected timeouts or connection churn under load.

Overview
Adds an opt-in maintenance notifications feature (MaintenanceNotificationsConfig + TimeoutOptions) that enables CLIENT MAINT_NOTIFICATIONS ON and registers a new Connection.MaintenanceEventConsumer to react to RESP3 PUSH events.

On maintenance PUSH types like MIGRATING/FAILING_OVER, connections temporarily relax SO_TIMEOUT (separate relaxed values for blocking vs non-blocking commands). On MOVING, the connection marks itself for disposal and the owning ConnectionPool rebinds its ConnectionFactory/DefaultJedisSocketFactory to the new HostAndPort and clears idle connections.

Updates test infrastructure (TcpMockServer, RespResponse) to emit typed RESP3 push messages, and adds/extends unit tests covering relaxed timeout transitions and proactive rebind behavior (including new UnifiedJedisProactiveRebindTest).

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

ggivo added 30 commits March 24, 2026 10:22
   - Preparation step for processing custom push notifications
   - Push notification can appear out-of band in-between executed commands
   - Current Connection implementation does not support out of band Push notifications
   - Meaning it will crash if "CLIENT TRACKING ON is enabled" on regular Jedis Connection and "invalidation" push event is triggered

 This commit provides a way to register push handler for the connection which process incoming push messages, before actual command is executed.  To preserve backward compatibility unprocessed push messages are forward to application logic as before.

   - By default Connection will start with NOOP push handler which marks any incoming push event as processed and skips it
   - On subcsribe/psubscribe a dedicated push handler is registered which propagates to the app only supported push  vents such as (message, subscribe, unsubscribe ...)
   - CacheConection is refactored to use a push handler handling "invalidate" push events only, and skipping any other

# Conflicts:
#	src/main/java/redis/clients/jedis/Connection.java
#	src/test/java/redis/clients/jedis/commands/jedis/PublishSubscribeCommandsTest.java
This commit adds a new PushHandlerChain class that implements the Chain of
Responsibility pattern for Redis RESP3 push message handling. Key features:

- Allows composing multiple PushHandlers in a processing chain
- Push events propagate through the complete chain in sequence
- Events marked as not processed are propagated to the client application
- Provides both constructor-based and fluent builder API for chain creation
- Includes predefined handlers for common use cases (CONSUME_ALL, PROPAGATE_ALL)
- Supports immutable chain transformations via methods like then(),

The chain approach provides a flexible way to handle different types of push
messages (invalidations, pub/sub, etc.) with specialized handlers while
maintaining a clean separation of concerns.

Example usage:
  PushHandlerChain chain = PushHandlerChain.of(loggingHandler)
      .then(invalidationHandler)
      .then(PushHandlerChain.PROPAGATE_PUB_SUB_PUSH_HANDLER);
  - code clean up
  - added relaxed timeout configuration
  - fix unit tests
Register PushInvalidateConsumer after cache is initialised
ConenctionFactory should be rebound before triggering the disposal of Idle connection, so that any newly creaetd are using the proper hostname
Issue : If Maintenace notifications are received during blocking command, relaxTimeout is enforced instead of infinit timeout.

Fix: Introduce dedicated relax timeout setting for blocking commands. It will fall back to infinit timeout if not set
   - Mark all pushes by default as processed
   - Remove CONSUME_ALL_HANDLER
 - Use existing ReflectionTestUtil instead of ReflectionTestUtils.java
 - address connection pool now uses builder - socketFactory not accessible
 - test should now use Endpoints
 - ListenerNotificationConsumer from Jedis
        moved to Connection
 - fix PushMessageNotificationTest
 - fix pom.xml missing includes tag
 - ConnectionTestHelper is obsolete after rebase
 - fix A MIGRATING event on connection A triggers AdaptiveTimeoutHandler for all connections
ggivo added 9 commits April 17, 2026 09:48
…u-notifications-rebased-wo-generic-push-listeners

# Conflicts:
#	pom.xml
#	src/main/java/redis/clients/jedis/Connection.java
#	src/test/java/redis/clients/jedis/ConnectionMockTest.java
MIGRATING <seq_number> <time> <shard_id-s>:
MIGRATED <seq_number> <shard_id-s>
FAILING_OVER <seq_number> <time> <shard_id-s>
FAILED_OVER <seq_number> <shard_id-s>
MOVING <seq_number> <time> <endpoint>
…TIONS ON handshake command

 - add maint notification handshake (CLIENT MAINT_NOTIFICATIONS ON)  - Move TimeoutOptions from JedisClientConfig to MaintenanceNotificationsConfig
 - Remove proactiveRebindEnabled flag from JedisClientConfig
Copy link
Copy Markdown

@cursor cursor Bot left a comment

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 and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 67e5b27. Configure here.

Comment thread src/main/java/redis/clients/jedis/Connection.java
ggivo added 19 commits May 5, 2026 17:36
Replace string-based type checking with byte array comparisons using
Arrays.equals(). PushMessage.getType() now returns byte[] directly
from content.get(0) without decoding or caching.

Adds *_BYTES constants to PushMessageTypes for efficient comparison.
 - npe guard
 - check invalidation message format
 - fix tests
…cations' into feature/hu-notifications-rebased-wo-generic-push-listeners
Base automatically changed from topic/ggivo/CAE-2660-push-notifications to master May 20, 2026 08:30
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.

2 participants