All Downloads are FREE. Search and download functionalities are using the official Maven repository.

reactivefeign.retry.BasicReactiveRetryPolicy Maven / Gradle / Ivy

/**
 * Copyright 2018 The Feign Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package reactivefeign.retry;

import feign.ExceptionPropagationPolicy;
import feign.RetryableException;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

import java.time.Clock;
import java.util.Date;

/**
 * @author Sergii Karpenko
 */
public class BasicReactiveRetryPolicy extends SimpleReactiveRetryPolicy{

  private final int maxRetries;
  private final long periodInMs;
  private final Clock clock;

  private BasicReactiveRetryPolicy(
          int maxRetries, long periodInMs,
          Clock clock, Scheduler scheduler,
          ExceptionPropagationPolicy exceptionPropagationPolicy){
    super(scheduler, exceptionPropagationPolicy);
    this.maxRetries = maxRetries;
    this.periodInMs = periodInMs;
    this.clock = clock;
  }

  public static SimpleReactiveRetryPolicy retry(int maxRetries) {
    return new BasicReactiveRetryPolicy.Builder().setMaxRetries(maxRetries).build();
  }

  public static SimpleReactiveRetryPolicy retryWithBackoff(int maxRetries, long periodInMs) {
    return new BasicReactiveRetryPolicy.Builder().setMaxRetries(maxRetries).setBackoffInMs(periodInMs).build();
  }

  public static SimpleReactiveRetryPolicy retryWithBackoff(int maxRetries, long periodInMs, Scheduler scheduler) {
    return new Builder().setMaxRetries(maxRetries).setBackoffInMs(periodInMs).setScheduler(scheduler).build();
  }

  @Override
  public long retryDelay(Throwable error, int attemptNo) {
    if (attemptNo <= maxRetries) {
      if(periodInMs > 0) {
        long delay;
        Long retryAfter;
        // "Retry-After" header set
        if (error instanceof RetryableException re && (retryAfter = re.retryAfter()) != null) {
          delay = retryAfter - clock.millis();
          delay = Math.min(delay, periodInMs);
          delay = Math.max(delay, 0);
        } else {
          delay = periodInMs;
        }
        return delay;
      } else {
        return 0;
      }
    } else {
      return -1;
    }
  }

  @Override
  public int maxAllowedRetries() {
    return maxRetries;
  }

  public static class Builder implements ReactiveRetryPolicy.Builder{
    private int maxRetries;
    private long backoffInMs = 0;
    private ExceptionPropagationPolicy exceptionPropagationPolicy;
    private Scheduler scheduler = Schedulers.parallel();
    private Clock clock = Clock.systemUTC();

    public Builder setMaxRetries(int maxRetries) {
      this.maxRetries = maxRetries;
      return this;
    }

    public Builder setBackoffInMs(long backoffInMs) {
      this.backoffInMs = backoffInMs;
      return this;
    }

    public Builder setExceptionPropagationPolicy(ExceptionPropagationPolicy exceptionPropagationPolicy) {
      this.exceptionPropagationPolicy = exceptionPropagationPolicy;
      return this;
    }

    Builder setClock(Clock clock) {
      this.clock = clock;
      return this;
    }

    Builder setScheduler(Scheduler scheduler) {
      this.scheduler = scheduler;
      return this;
    }

    public BasicReactiveRetryPolicy build(){
      return new BasicReactiveRetryPolicy(maxRetries, backoffInMs, clock, scheduler, exceptionPropagationPolicy);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy