3030import reactor .core .publisher .Mono ;
3131import reactor .netty .Connection ;
3232import reactor .retry .Backoff ;
33+ import reactor .retry .Jitter ;
3334import reactor .retry .Repeat ;
3435import reactor .retry .RepeatContext ;
3536import reactor .retry .Retry ;
@@ -70,7 +71,7 @@ private static <T> List<T> toList(T... items) {
7071 @ Override
7172 public List <String > shortcutFieldOrder () {
7273 return Arrays .asList ("retries" , "statuses" , "methods" , "backoff.firstBackoff" , "backoff.maxBackoff" ,
73- "backoff.factor" , "backoff.basedOnPreviousValue" );
74+ "backoff.factor" , "backoff.basedOnPreviousValue" , "jitter.randomFactor" , "timeout" );
7475 }
7576
7677 @ Override
@@ -124,9 +125,16 @@ public GatewayFilter apply(RetryConfig retryConfig) {
124125 if (backoff != null ) {
125126 statusCodeRepeat = statusCodeRepeat .backoff (getBackoff (backoff ));
126127 }
128+ JitterConfig jitter = retryConfig .getJitter ();
129+ if (jitter != null ) {
130+ statusCodeRepeat = statusCodeRepeat .jitter (getJitter (jitter ));
131+ }
132+ Duration timeout = retryConfig .getTimeout ();
133+ if (timeout != null ) {
134+ statusCodeRepeat = statusCodeRepeat .timeout (timeout );
135+ }
127136 }
128137
129- // TODO: support timeout, backoff, jitter, etc... in Builder
130138
131139 Retry <ServerWebExchange > exceptionRetry = null ;
132140 if (!retryConfig .getExceptions ().isEmpty ()) {
@@ -163,6 +171,14 @@ public GatewayFilter apply(RetryConfig retryConfig) {
163171 if (backoff != null ) {
164172 exceptionRetry = exceptionRetry .backoff (getBackoff (backoff ));
165173 }
174+ JitterConfig jitter = retryConfig .getJitter ();
175+ if (jitter != null ) {
176+ statusCodeRepeat = statusCodeRepeat .jitter (getJitter (jitter ));
177+ }
178+ Duration timeout = retryConfig .getTimeout ();
179+ if (timeout != null ) {
180+ statusCodeRepeat = statusCodeRepeat .timeout (timeout );
181+ }
166182 }
167183
168184 GatewayFilter gatewayFilter = apply (retryConfig .getRouteId (), statusCodeRepeat , exceptionRetry );
@@ -204,6 +220,10 @@ private Backoff getBackoff(BackoffConfig backoff) {
204220 backoff .basedOnPreviousValue );
205221 }
206222
223+ private Jitter getJitter (JitterConfig jitter ) {
224+ return Jitter .random (jitter .randomFactor );
225+ }
226+
207227 public boolean exceedsMaxIterations (ServerWebExchange exchange , RetryConfig retryConfig ) {
208228 Integer iteration = exchange .getAttribute (RETRY_ITERATION_KEY );
209229
@@ -295,6 +315,10 @@ public static class RetryConfig implements HasRouteId {
295315
296316 private BackoffConfig backoff ;
297317
318+ private JitterConfig jitter ;
319+
320+ private Duration timeout ;
321+
298322 public RetryConfig allMethods () {
299323 return setMethods (HttpMethod .values ());
300324 }
@@ -307,6 +331,30 @@ public void validate() {
307331 if (this .backoff != null ) {
308332 this .backoff .validate ();
309333 }
334+ if (this .jitter != null ) {
335+ this .jitter .validate ();
336+ }
337+ if (this .timeout != null ) {
338+ Assert .isTrue (!timeout .isNegative (), "timeout should be >= 0" );
339+ }
340+ }
341+
342+ public Duration getTimeout () {
343+ return timeout ;
344+ }
345+
346+ public RetryConfig setTimeout (Duration timeout ) {
347+ this .timeout = timeout ;
348+ return this ;
349+ }
350+
351+ public JitterConfig getJitter () {
352+ return jitter ;
353+ }
354+
355+ public RetryConfig setJitter (JitterConfig jitter ) {
356+ this .jitter = jitter ;
357+ return this ;
310358 }
311359
312360 public BackoffConfig getBackoff () {
@@ -439,4 +487,28 @@ public void setBasedOnPreviousValue(boolean basedOnPreviousValue) {
439487
440488 }
441489
490+ public static class JitterConfig {
491+
492+ private double randomFactor = 0.5 ;
493+
494+ public void validate () {
495+ Assert .isTrue (randomFactor >= 0 && randomFactor <= 1 , "random factor must be between 0 and 1 (default 0.5)" );
496+ }
497+
498+ public JitterConfig () {
499+ }
500+
501+ public JitterConfig (double randomFactor ) {
502+ this .randomFactor = randomFactor ;
503+ }
504+
505+ public double getRandomFactor () {
506+ return randomFactor ;
507+ }
508+
509+ public void setRandomFactor (double randomFactor ) {
510+ this .randomFactor = randomFactor ;
511+ }
512+ }
513+
442514}
0 commit comments