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

com.softicar.platform.common.core.retry.AbstractRetrier Maven / Gradle / Ivy

Go to download

The SoftiCAR Platform is a lightweight, Java-based library to create interactive business web applications.

There is a newer version: 50.0.0
Show newest version
package com.softicar.platform.common.core.retry;

import com.softicar.platform.common.core.thread.sleep.Sleep;
import com.softicar.platform.common.core.throwable.Throwables;
import java.io.IOException;
import java.time.Duration;
import java.util.Objects;
import java.util.function.Function;

/**
 * Abstract utility class to retry the execution of a method.
 * 

* Please note that in case of an {@link InterruptedException} or an exception * caused by an {@link InterruptedException}, a retry will not be performed. * * @author Oliver Richers */ public abstract class AbstractRetrier> { public static final int DEFAULT_TRY_COUNT = 3; public static final Duration DEFAULT_RETRY_DELAY = Duration.ZERO; private int tryCount; private Duration retryDelay; private Function retryDecider; public AbstractRetrier() { this.tryCount = DEFAULT_TRY_COUNT; this.retryDelay = DEFAULT_RETRY_DELAY; this.retryDecider = exception -> true; } /** * Defines the number of tries. *

* This is the maximum number of tries that the given payload method is * executed. The minimum is 1 and the default is 3. * * @param tryCount * the number of tries (minimum of 1) * @return this object * @throws IllegalArgumentException * if the try count is less than one */ public T setTryCount(int tryCount) { if (tryCount < 1) { throw new IllegalArgumentException(String.format("Illegal maximum try count of %s. Must be greater or equal to 1.", tryCount)); } this.tryCount = tryCount; return getThis(); } /** * Defines the number of retries. *

* This is the maximum number of retries for the given payload method. The * minimum is 0. *

* This is only a convenience method, which actually calls * {@link #setTryCount(int)} with the count increased by one. * * @param retryCount * the number of tries (minimum of 0) * @return this object * @throws IllegalArgumentException * if the retry count is negative */ public T setRetryCount(int retryCount) { if (retryCount < 0) { throw new IllegalArgumentException(String.format("Illegal retry count of %s. Must be greater or equal to 0.", tryCount)); } return setTryCount(retryCount + 1); } /** * Defines the {@link Duration} to wait after a failed execution, before * trying again. * * @param retryDelay * the retry delay (never null or negative); the default * is {@link Duration#ZERO} * @throws IllegalArgumentException * if the delay is negative * @return this object */ public T setRetryDelay(Duration retryDelay) { if (retryDelay.isNegative()) { throw new IllegalArgumentException(String.format("The retry delay may not be negative.")); } this.retryDelay = retryDelay; return getThis(); } /** * Defines a function to check for a caught exception if the execution shall * be tried again. *

* This is useful for example if you only want to retry the execution in * case of an {@link IOException}. *

* Please note that in case of an {@link InterruptedException} or an * exception caused by an {@link InterruptedException}, a retry will not be * performed. * * @param retryDecider * the deciding function * @return this object */ public T setRetryDecider(Function retryDecider) { Objects.nonNull(retryDecider); this.retryDecider = retryDecider; return getThis(); } protected void executeRetryLoop() { int i = 1; while (true) { try { executeTry(); return; } catch (Exception exception) { if (Throwables.isCausedBy(InterruptedException.class, exception)) { throw exception; } else if (i < tryCount && retryDecider.apply(exception)) { ++i; } else { throw exception; } } if (!retryDelay.isZero()) { Sleep.sleep(retryDelay); } } } protected abstract void executeTry(); protected abstract T getThis(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy