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

org.bitcoinj.utils.ExponentialBackoff Maven / Gradle / Ivy

There is a newer version: 0.17-beta1
Show newest version
/*
 * Copyright 2013 Google Inc.
 *
 * 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 org.bitcoinj.utils;

import org.bitcoinj.base.internal.TimeUtils;

import java.time.Duration;
import java.time.Instant;

import static org.bitcoinj.base.internal.Preconditions.checkArgument;

/**
 * 

Tracks successes and failures and calculates a time to retry the operation.

* *

The retries are exponentially backed off, up to a maximum interval. On success the back off interval is reset.

*/ public class ExponentialBackoff implements Comparable { public static final Duration DEFAULT_INITIAL_INTERVAL = Duration.ofMillis(100); public static final float DEFAULT_MULTIPLIER = 1.1f; public static final Duration DEFAULT_MAXIMUM_INTERVAL = Duration.ofSeconds(30); private Duration backoff; private Instant retryTime; private final Params params; /** * Parameters to configure a particular kind of exponential backoff. */ public static class Params { private final Duration initialInterval; private final float multiplier; private final Duration maximumInterval; /** * @param initialInterval the initial interval to wait * @param multiplier the multiplier to apply on each failure * @param maximumInterval the maximum interval to wait */ public Params(Duration initialInterval, float multiplier, Duration maximumInterval) { checkArgument(multiplier > 1.0f, () -> "multiplier must be greater than 1.0: " + multiplier); checkArgument(maximumInterval.compareTo(initialInterval) >= 0, () -> "maximum must not be less than initial: " + maximumInterval); this.initialInterval = initialInterval; this.multiplier = multiplier; this.maximumInterval = maximumInterval; } /** * Construct params with default values. */ public Params() { initialInterval = DEFAULT_INITIAL_INTERVAL; multiplier = DEFAULT_MULTIPLIER; maximumInterval = DEFAULT_MAXIMUM_INTERVAL; } } public ExponentialBackoff(Params params) { this.params = params; trackSuccess(); } /** Track a success - reset back off interval to the initial value */ public final void trackSuccess() { backoff = params.initialInterval; retryTime = TimeUtils.currentTime(); } /** Track a failure - multiply the back off interval by the multiplier */ public void trackFailure() { retryTime = TimeUtils.currentTime().plus(backoff); backoff = Duration.ofMillis((long) (backoff.toMillis() * params.multiplier)); if (backoff.compareTo(params.maximumInterval) > 0) backoff = params.maximumInterval; } /** Get the next time to retry */ public Instant retryTime() { return retryTime; } /** * Get the next time to retry, in milliseconds since the epoch * @deprecated use {@link #retryTime()} **/ @Deprecated public long getRetryTime() { return retryTime.toEpochMilli(); } @Override public int compareTo(ExponentialBackoff other) { // note that in this implementation compareTo() is not consistent with equals() return retryTime.compareTo(other.retryTime); } @Override public String toString() { return "ExponentialBackoff retry=" + retryTime + " backoff=" + backoff.toMillis() + " ms"; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy