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

io.polaris.core.lang.Retry Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
package io.polaris.core.lang;

import io.polaris.core.log.ILogger;
import io.polaris.core.log.ILoggers;

import java.util.concurrent.Callable;

/**
 * @author Qt
 * @since 1.8
 */
public class Retry {
	private static final ILogger log = ILoggers.of(Retry.class);


	public static  T doRetry(Callable callable, int retryTimes, long sleepTimeInMilliSecond,
															Class... retryExceptionClasses) throws Exception {
		return doRetry(callable, retryTimes, sleepTimeInMilliSecond, false, retryExceptionClasses);
	}

	public static  T doRetry(Callable callable, int retryTimes, long sleepTimeInMilliSecond, boolean exponential,
															Class... retryExceptionClasses) throws Exception {
		if (null == callable) {
			throw new IllegalArgumentException("入参callable不能为空!");
		}
		if (retryTimes < 1) {
			throw new IllegalArgumentException("入参retryTimes不能小于1!");
		}
		Throwable saveException = null;
		for (int i = 0; i <= retryTimes; i++) {
			try {
				return callable.call();
			} catch (Throwable e) {
				saveException = e;
				if (!waitForRetry(i, retryTimes, sleepTimeInMilliSecond, exponential, saveException, retryExceptionClasses)) {
					throw saveException instanceof Exception ?
						(Exception) saveException : new RuntimeException(saveException);
				}
			}
		}
		throw saveException instanceof Exception ?
			(Exception) saveException : new RuntimeException(saveException);
	}

	public static void doRetry(Runnable runnable, int retryTimes, long sleepTimeInMilliSecond,
														 Class... retryExceptionClasses) {
		doRetry(runnable, retryTimes, sleepTimeInMilliSecond, false, retryExceptionClasses);
	}

	public static void doRetry(Runnable runnable, int retryTimes, long sleepTimeInMilliSecond, boolean exponential,
														 Class... retryExceptionClasses) {
		if (null == runnable) {
			throw new IllegalArgumentException("入参runnable不能为空!");
		}
		if (retryTimes < 1) {
			throw new IllegalArgumentException("入参retryTimes不能小于1!");
		}
		Throwable saveException = null;
		for (int i = 0; i <= retryTimes; i++) {
			try {
				runnable.run();
				return;
			} catch (Throwable e) {
				saveException = e;
				if (!waitForRetry(i, retryTimes, sleepTimeInMilliSecond, exponential, saveException, retryExceptionClasses)) {
					throw saveException instanceof RuntimeException ?
						(RuntimeException) saveException : new RuntimeException(saveException);
				}
			}
		}
		throw saveException instanceof RuntimeException ?
			(RuntimeException) saveException : new RuntimeException(saveException);
	}

	private static boolean waitForRetry(int retryTime, int retryTimes, long sleepTimeInMilliSecond, boolean exponential, Throwable exception, Class[] retryExceptionClasses) {
		boolean retryable = true;
		if (retryExceptionClasses != null && retryExceptionClasses.length > 0) {
			retryable = false;
			for (Class retryExceptionClass : retryExceptionClasses) {
				if (retryExceptionClass.isInstance(exception)) {
					retryable = true;
					break;
				}
			}
		}
		if (!retryable) {
			return false;
		}
		if (retryTime < retryTimes) {
			if (sleepTimeInMilliSecond > 0) {
				long sleepMills = sleepTimeInMilliSecond;
				if (exponential) {
					sleepMills = sleepTimeInMilliSecond * (long) Math.pow(2, retryTime);
				}
				log.info("程序执行过程失败! 预计在{}ms后第{}次重试", sleepMills, retryTime + 1);
				try {
					Thread.sleep(sleepMills);
				} catch (InterruptedException interruptedException) {
				}
			} else {
				log.info("程序执行过程失败! 第{}次重试", retryTime + 1);
			}
		}
		return true;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy