/* * Copyright 2017 LINE Corporation * * LINE Corporation licenses this file to you 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 com.linecorp.armeria.client.retry; import static com.linecorp.armeria.client.retry.FixedBackoff.NO_DELAY; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; import java.util.function.Supplier; /** * Control back off between attempts in a single retry operation. */ @FunctionalInterface public interface Backoff { /** * Returns a {@link Backoff} that that will never wait between attempts. */ static Backoff withoutDelay() { return NO_DELAY; } /** * Returns a {@link Backoff} that waits a fixed interval between attempts. */ static Backoff fixed(long intervalMillis) { return new FixedBackoff(intervalMillis); } /** * Returns a {@link Backoff} that waits an exponentially-increasing amount of time between attempts. */ static Backoff exponential(long minIntervalMillis, long maxIntervalMillis) { return exponential(minIntervalMillis, maxIntervalMillis, 2.0); } /** * Returns a {@link Backoff} that waits an exponentially-increasing amount of time between attempts. */ static Backoff exponential(long minIntervalMillis, long maxIntervalMillis, double multiplier) { return new ExponentialBackoff(minIntervalMillis, maxIntervalMillis, multiplier); } /** * Returns the number of milliseconds to wait for before attempting a retry. * * @param numAttemptsSoFar the number of attempts made by a client so far, including the first attempt and * its following retries. * * @return the number of milliseconds to wait for before attempting a retry, * or a negative value if no further retry has to be made. * * @throws IllegalArgumentException if {@code numAttemptsSoFar} is equal to or less than {@code 0} */ long nextIntervalMillis(int numAttemptsSoFar); /** * Returns a {@link Backoff} that provides an interval that increases using * <a href="https://www.awsarchitectureblog.com/2015/03/backoff.html">full jitter</a> strategy. */ default Backoff withJitter(long minJitterMillis, long maxJitterMillis) { return withJitter(minJitterMillis, maxJitterMillis, ThreadLocalRandom::current); } /** * Returns a {@link Backoff} that provides an interval that increases using * <a href="https://www.awsarchitectureblog.com/2015/03/backoff.html">full jitter</a> strategy. */ default Backoff withJitter(long minJitterMillis, long maxJitterMillis, Supplier<Random> randomSupplier) { return new JitterAddingBackoff(this, minJitterMillis, maxJitterMillis, randomSupplier); } /** * Returns a {@link Backoff} which limits the number of attempts up to the specified value. */ default Backoff withMaxAttempts(int maxAttempts) { return new AttemptLimitingBackoff(this, maxAttempts); } }