Last active
March 9, 2021 08:56
-
-
Save codethereforam/982afcf3f4017c75601694be35bc0af2 to your computer and use it in GitHub Desktop.
cool retrying
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* cool retrying | |
* | |
* @author yanganyu | |
* @date 2021/3/9 | |
*/ | |
@Slf4j | |
public class CoolRetrying<T> { | |
/** | |
* 重试次数 | |
*/ | |
private int retryTimes; | |
/** | |
* 间隔期间 | |
*/ | |
private Duration interval; | |
/** | |
* 重试方法 | |
*/ | |
private CheckedSupplier<T> retryingMethod; | |
/** | |
* 结果断言 | |
*/ | |
private Predicate<T> resultPredicate; | |
/** | |
* 是否快速失败(true: 有异常立即失败;false:有异常继续) | |
*/ | |
private boolean failFastWhenException = true; | |
public CoolRetrying() { | |
} | |
public CoolRetrying<T> interval(Duration pollDuration) { | |
this.interval = pollDuration; | |
return this; | |
} | |
public CoolRetrying<T> exec(CheckedSupplier<T> supplier) { | |
retryingMethod = supplier; | |
return this; | |
} | |
public CoolRetrying<T> until(Predicate<T> predicate) { | |
resultPredicate = predicate; | |
return this; | |
} | |
public CoolRetrying<T> retryTimes(int retryTimes) { | |
this.retryTimes = retryTimes; | |
return this; | |
} | |
public CoolRetrying<T> failFastWhenException(boolean failFastWhenException) { | |
this.failFastWhenException = failFastWhenException; | |
return this; | |
} | |
public T bootstrap() throws Exception { | |
this.validateParameters(); | |
T result = null; | |
for (int attemptNumber = 1; attemptNumber <= retryTimes; attemptNumber++) { | |
try { | |
result = retryingMethod.get(); | |
} catch (Exception e) { | |
if (failFastWhenException) { | |
throw e; | |
} else { | |
log.error("coolRetrying execute exception at No.{} times", attemptNumber, e); | |
} | |
} | |
if (resultPredicate.test(result)) { | |
return result; | |
} | |
if (interval != null) { | |
try { | |
Thread.sleep(interval.toMillis()); | |
} catch (InterruptedException e) { | |
Thread.currentThread().interrupt(); | |
throw new RuntimeException(e); | |
} | |
} | |
} | |
return result; | |
} | |
private void validateParameters() { | |
if (retryTimes < 1) { | |
throw new IllegalArgumentException("retryTimes can not < 1"); | |
} | |
Objects.requireNonNull(retryingMethod, "retryingMethod can not be null"); | |
Objects.requireNonNull(resultPredicate, "resultPredicate can not be null"); | |
} | |
public static void main(String[] args) throws Exception { | |
String result = new CoolRetrying<String>() | |
.exec(() -> UUID.randomUUID().toString()) | |
.until(s -> s.startsWith("a")) | |
.interval(Duration.ofMillis(2000)) | |
.retryTimes(100) | |
.failFastWhenException(false) | |
.bootstrap(); | |
System.out.println(result); | |
} | |
} | |
/** | |
* simulate 'java.util.function.Supplier' | |
* | |
* @author yanganyu | |
* @date 2021/3/9 | |
*/ | |
@FunctionalInterface | |
public interface CheckedSupplier<T> { | |
/** | |
* Gets a result. | |
* | |
* @return a result | |
* @throws Exception exception | |
*/ | |
T get() throws Exception; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment