Skip to content

[maintenance events] Expose maintenance events as public API - #4618

Open
atakavci wants to merge 10 commits into
redis:feature/sch-1from
atakavci:ali/exposeEvents
Open

[maintenance events] Expose maintenance events as public API#4618
atakavci wants to merge 10 commits into
redis:feature/sch-1from
atakavci:ali/exposeEvents

Conversation

@atakavci

@atakavci atakavci commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Closes #4604

Summary

Adds a public, read-only way for applications to observe server maintenance events (MOVING, MIGRATING, MIGRATED, FAILING_OVER, FAILED_OVER). Users register a MaintenanceEventListener on MaintenanceNotificationsConfig and receive typed MaintenanceEvent objects, without any exposure to internal connection state. Internally, the old per-type listener contract is split off into a package-private handler so the public surface stays minimal.

Key Decisions & Assumptions

  • The public MaintenanceEventListener gets a single onEvent(MaintenanceEvent) method and never sees the Connection — only the event and its typed getters. The internal per-type contract (onMoving, onMigrating, …, each with a Connection) moves to a new package-private MaintenanceEventHandler.
  • MaintenanceEvent becomes public; its subclasses are now public static nested classes with accessors (getSeq, getType, getTarget, getTtlSeconds, getShardIds) plus an EventType enum.
  • Handler dispatch order is deliberate: a LinkedHashSet guarantees the internal controller runs first (completing rebind/handoff bookkeeping) before the user's listener adapter runs. When no custom listener is configured, a singleton set is used.
  • MaintenanceEventListenerAdapter bridges the public listener to the internal handler and drops stale/duplicate events by comparing sequence numbers (CAS on the last seen seq).

Behavioral / Conceptual Changes

  • Applications can now register a listener via MaintenanceNotificationsConfig.builder().maintenanceListener(...) and be notified of maintenance events.
  • Per-connection listener registration (Connection#addMaintenanceEventListener / remove / get) is removed; the handler set is now assembled by MaintenanceAwareVisitor at init time.
  • Events delivered to a public listener are de-duplicated and ordered by seq; out-of-order or repeated events are dropped.

Testing

Existing maintenance tests were updated to the renamed internal MaintenanceEventHandler type (recording listeners and the consumer's set signature); the changes are mechanical and preserve the prior coverage of dispatch and listener-exception propagation.

Notes

  • pom.xml widens a plugin include to **/*Event.java, and logback-test.xml lowers MaintenanceAwareVisitor logging to WARN.
  • args/LatencyEvent.java changes are indentation/formatting only.

Note

Medium Risk
Public API and listener wiring changes affect connection-pool rebind and timeout behavior during maintenance; user callbacks run on the read thread after internal controller logic, so slow or throwing listeners can impact I/O.

Overview
Exposes Redis server maintenance notifications (MOVING, MIGRATING/MIGRATED, FAILING_OVER/FAILED_OVER) as a public API so apps can observe events without touching Connection internals.

MaintenanceEvent is now public with an EventType enum and getters (getSeq, getType, getTtlSeconds, getShardIds, getTarget); per-type classes stay nested static types. MaintenanceEventListener is public with a single onEvent(MaintenanceEvent) callback (no per-type methods, no Connection argument).

Registration moves to MaintenanceNotificationsConfig.builder().maintenanceListener(...). MaintenanceAwareVisitor builds a per-connection handler set: internal MaintenanceEventController first (rebind/timeouts), then MaintenanceEventListenerAdapter when a listener is configured. The adapter deduplicates by sequence before calling the user listener.

Connection no longer stores or exposes maintenance listeners (add/remove/getMaintenanceEventListener removed). Internal dispatch uses package-private MaintenanceEventHandler; MaintenanceEventConsumer fans out to handlers on the read thread unchanged in spirit.

pom.xml adds **/*Event.java to formatter includes; LatencyEvent is formatting-only; test/log tweaks follow the handler rename.

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

Copilot AI 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.

Pull request overview

This PR promotes Redis maintenance push notifications to a supported public API by making MaintenanceEvent/MaintenanceEventListener and per-event subclasses public, and by moving listener registration to MaintenanceNotificationsConfig (wired per-connection by MaintenanceAwareVisitor).

Changes:

  • Split maintenance event subclasses into top-level public *Event types with public read accessors (seq/ttl/shards/target).
  • Add MaintenanceNotificationsConfig.Builder#maintenanceListener(...) and wire the config listener alongside the internal controller in MaintenanceAwareVisitor.
  • Remove per-Connection maintenance listener storage and related APIs; update formatter includes to cover the new event files.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/main/java/redis/clients/jedis/MaintenanceEvent.java Makes base event type public and adds getSeq(); removes nested subclasses.
src/main/java/redis/clients/jedis/MaintenanceEventListener.java Makes listener interface public (but needs Javadoc update after API move).
src/main/java/redis/clients/jedis/MovingEvent.java New top-level public event type with getters.
src/main/java/redis/clients/jedis/MigratingEvent.java New top-level public event type with getters.
src/main/java/redis/clients/jedis/MigratedEvent.java New top-level public event type with getters.
src/main/java/redis/clients/jedis/FailingOverEvent.java New top-level public event type with getters.
src/main/java/redis/clients/jedis/FailedOverEvent.java New top-level public event type with getters.
src/main/java/redis/clients/jedis/MaintenanceNotificationsConfig.java Adds config-level listener registration + getter (needs immutability/thread-safety tweak + tests).
src/main/java/redis/clients/jedis/MaintenanceAwareVisitor.java Builds per-connection listener set from controller + config listener (HashSet sizing can be improved).
src/main/java/redis/clients/jedis/Connection.java Removes maintenance listener set and related add/remove/get APIs.
src/main/java/redis/clients/jedis/args/LatencyEvent.java Formatting-only changes.
pom.xml Adds **/*Event.java to formatter plugin includes to cover newly split files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/redis/clients/jedis/MaintenanceNotificationsConfig.java Outdated
Comment thread src/main/java/redis/clients/jedis/MaintenanceEvent.java Outdated
Comment thread src/main/java/redis/clients/jedis/MaintenanceEventListener.java Outdated
Comment thread src/main/java/redis/clients/jedis/MaintenanceAwareVisitor.java Outdated
Comment thread src/main/java/redis/clients/jedis/MaintenanceAwareVisitor.java Outdated

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

Fix All in Cursor

Reviewed by Cursor Bugbot for commit ce7e617. Configure here.

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

Copilot AI 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.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 8 comments.

Comment on lines 3 to 6
/**
* A server maintenance event. One subclass per type, each carrying the fields relevant to that
* type. Dispatched to a {@link MaintenanceEventListener} via {@link #accept}.
* type. Dispatched to a {@link MaintenanceEventHandler} when provided.
*/
* {@code [MOVING, seq, time_s, host:port]} — endpoint moves to {@code target} within
* {@code ttlSeconds}.
*/
static final class MovingEvent extends MaintenanceEvent {
* {@code [MIGRATING, seq, time_s, shards]} — {@code time_s} = starts-within; {@code shardIds}
* diagnostic.
*/
static final class MigratingEvent extends MaintenanceEvent {
}
}
/** {@code [MIGRATED, seq, shards]} — terminator; no time_s on the wire. */
static final class MigratedEvent extends MaintenanceEvent {
* {@code [FAILING_OVER, seq, time_s, shards]} — {@code time_s} = starts-within; {@code shardIds}
* diagnostic.
*/
static final class FailingOverEvent extends MaintenanceEvent {
final class FailedOverEvent extends MaintenanceEvent {
final String shardIds;
/** {@code [FAILED_OVER, seq, shards]} — terminator. */
static final class FailedOverEvent extends MaintenanceEvent {
Comment on lines 1 to 7
package redis.clients.jedis;

/**
* Typed listener for server maintenance push events. Registered on a {@link Connection} via
* {@link Connection#addMaintenanceEventListener}; the connection dispatches each parsed event to
* the matching method synchronously on its read thread, before the triggering read returns. A
* listener may mutate the delivering connection (e.g. relax timeouts, request rebind); exceptions
* propagate to the read loop.
*/
interface MaintenanceEventListener {
public interface MaintenanceEventListener {

void onMoving(MovingEvent e, Connection c);
void onEvent(MaintenanceEvent e);

void onMigrating(MigratingEvent e, Connection c);

void onMigrated(MigratedEvent e, Connection c);

void onFailingOver(FailingOverEvent e, Connection c);

void onFailedOver(FailedOverEvent e, Connection c);
}
private final MaintenanceEventListener listener;
private final AtomicReference<MaintenanceEvent> lastEvent = new AtomicReference<>();

public MaintenanceEventListenerAdapter(MaintenanceEventListener listener) {
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