-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Add configurable retry delay for Sentinel reconnection (#2864) #4379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
1487a9c
455a2cc
cf1fd45
0a86d1e
e10808b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,9 +1,12 @@ | ||||||
| package redis.clients.jedis.builders; | ||||||
|
|
||||||
| import java.time.Duration; | ||||||
| import java.util.Set; | ||||||
| import redis.clients.jedis.*; | ||||||
| import redis.clients.jedis.providers.ConnectionProvider; | ||||||
| import redis.clients.jedis.providers.SentineledConnectionProvider; | ||||||
| import redis.clients.jedis.util.Delay; | ||||||
| import redis.clients.jedis.util.JedisAsserts; | ||||||
|
|
||||||
| /** | ||||||
| * Builder for creating JedisSentineled instances (Redis Sentinel connections). | ||||||
|
|
@@ -16,11 +19,16 @@ | |||||
| public abstract class SentinelClientBuilder<C> | ||||||
| extends AbstractClientBuilder<SentinelClientBuilder<C>, C> { | ||||||
|
|
||||||
| private static final Delay DEFAULT_RESUBSCRIBE_DELAY = Delay.constant(Duration.ofMillis(5000)); | ||||||
|
|
||||||
| // Sentinel-specific configuration fields | ||||||
| private String masterName = null; | ||||||
| private Set<HostAndPort> sentinels = null; | ||||||
| private JedisClientConfig sentinelClientConfig = null; | ||||||
|
|
||||||
| // delay between re-subscribing to sentinel nodes after a disconnection | ||||||
| private Delay sentinellReconnectDelay = DEFAULT_RESUBSCRIBE_DELAY; | ||||||
|
|
||||||
| /** | ||||||
| * Sets the master name for the Redis Sentinel configuration. | ||||||
| * <p> | ||||||
|
|
@@ -60,6 +68,21 @@ public SentinelClientBuilder<C> sentinelClientConfig(JedisClientConfig sentinelC | |||||
| return this; | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Sets the delay between re-subscribing to sentinel node after a disconnection.* | ||||||
|
||||||
| * Sets the delay between re-subscribing to sentinel node after a disconnection.* | |
| * Sets the delay between re-subscribing to sentinel node after a disconnection. |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable name "sentinellReconnectDelay" contains a typo with double 'l'. It should be "sentinelReconnectDelay" (single 'l') to match the method name "sentinelReconnectDelay" and standard spelling.
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable name "sentinellReconnectDelay" contains a typo with double 'l'. It should be "sentinelReconnectDelay" (single 'l') to match the method name "sentinelReconnectDelay" and standard spelling.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| package redis.clients.jedis.util; | ||
|
|
||
| import java.time.Duration; | ||
| import java.util.concurrent.ThreadLocalRandom; | ||
|
|
||
| public abstract class Delay { | ||
|
|
||
| protected Delay() { | ||
| } | ||
|
|
||
| /** | ||
| * Calculate a specific delay based on the attempt. | ||
| * @param attempt the attempt to calculate the delay from. | ||
| * @return the calculated delay. | ||
| */ | ||
| public abstract Duration delay(long attempt); | ||
|
|
||
| /** | ||
| * Creates a constant delay. | ||
| * @param delay the constant delay duration | ||
| * @return a Delay that always returns the same duration | ||
| */ | ||
| public static Delay constant(Duration delay) { | ||
| return new ConstantDelay(delay); | ||
| } | ||
|
|
||
| /** | ||
| * Creates an exponential delay with equal jitter. Based on AWS exponential backoff strategy: | ||
| * https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ Formula: temp = | ||
| * min(upper, base * 2^attempt) sleep = temp/2 + random_between(0, temp/2) result = max(lower, | ||
| * sleep) | ||
| * @param lower the minimum delay duration (lower bound) | ||
| * @param upper the maximum delay duration (upper bound) | ||
| * @param base the base delay duration | ||
| * @return a Delay with exponential backoff and equal jitter | ||
| */ | ||
| public static Delay exponentialWithJitter(Duration lower, Duration upper, Duration base) { | ||
| return new EqualJitterDelay(lower, upper, base); | ||
| } | ||
|
|
||
| static class ConstantDelay extends Delay { | ||
|
|
||
| private final Duration delay; | ||
|
|
||
| ConstantDelay(Duration delay) { | ||
| this.delay = delay; | ||
| } | ||
|
|
||
| @Override | ||
| public Duration delay(long attempt) { | ||
| return delay; | ||
| } | ||
| } | ||
|
|
||
| static class EqualJitterDelay extends Delay { | ||
|
|
||
| private final long lowerMillis; | ||
| private final long upperMillis; | ||
| private final long baseMillis; | ||
|
|
||
| EqualJitterDelay(Duration lower, Duration upper, Duration base) { | ||
| this.lowerMillis = lower.toMillis(); | ||
| this.upperMillis = upper.toMillis(); | ||
| this.baseMillis = base.toMillis(); | ||
| } | ||
|
|
||
| @Override | ||
| public Duration delay(long attempt) { | ||
| // temp = min(upper, base * 2^attempt) | ||
| long exponential = baseMillis * (1L << Math.min(attempt, 62)); | ||
| long temp = Math.min(upperMillis, exponential); | ||
|
|
||
| // sleep = temp/2 + random_between(0, temp/2) | ||
| long half = temp / 2; | ||
| long jitter = ThreadLocalRandom.current().nextLong(half + 1); | ||
| long delayMillis = half + jitter; | ||
|
|
||
| // Apply lower bound | ||
| delayMillis = Math.max(lowerMillis, delayMillis); | ||
|
|
||
| return Duration.ofMillis(delayMillis); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable name "sentinellReconnectDelay" contains a typo with double 'l'. It should be "sentinelReconnectDelay" (single 'l') to match the method name "sentinelReconnectDelay" and standard spelling.