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

io.bdeploy.common.RetryableScope Maven / Gradle / Ivy

Go to download

Public API including dependencies, ready to be used for integrations and plugins.

There is a newer version: 7.3.6
Show newest version
package io.bdeploy.common;

import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RetryableScope {

    @FunctionalInterface
    public interface RetryableRunnable {

        public void run() throws Exception;
    }

    private static final Logger log = LoggerFactory.getLogger(RetryableScope.class);

    private final AtomicLong iterationCountMax = new AtomicLong(10);
    private final AtomicLong iterationTimeoutMs = new AtomicLong(100);

    private Consumer onException = e -> {
        log.debug("Retriable scope received exception: ", e);

        try {
            Thread.sleep(iterationTimeoutMs.get());
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
            throw new IllegalStateException("While handling retry: ", ie);
        }
    };

    private RetryableScope() {
        // intentionally left blank.
    }

    public static RetryableScope create() {
        return new RetryableScope();
    }

    /**
     * Replaces the default exception handler (including delay handling of retries) with a custom one.
     */
    public RetryableScope withExceptionHandler(Consumer e) {
        this.onException = e;
        return this;
    }

    /**
     * Sets the timeout the default exception handler will delay retries in milliseconds. The default is 100ms.
     */
    public RetryableScope withDelay(long ms) {
        this.iterationTimeoutMs.set(ms);
        return this;
    }

    /**
     * Sets the amount of retries that the action will be re-called in case of an exception. The default is 10.
     */
    public RetryableScope withMaxRetries(long amount) {
        this.iterationCountMax.set(amount);
        return this;
    }

    /**
     * Perform the given action. Retry execution up to {@link #withMaxRetries(long)} times, with a delay of
     * {@link #withDelay(long)} milliseconds between retries (given the exception and timeout handler has not been replaced using
     * {@link #withExceptionHandler(Consumer)}).
     */
    public void run(RetryableRunnable action) {
        boolean madeIt = false;
        Exception lastException = null;
        for (long i = 0; i < iterationCountMax.get(); ++i) {
            try {
                action.run();
                madeIt = true;
                break;
            } catch (Exception e) {
                lastException = e;
                onException.accept(e);
            }
        }

        if (!madeIt) {
            if (lastException != null) {
                throw new IllegalStateException(lastException);
            } else {
                throw new IllegalStateException("Out of retries");
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy