栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 重试小工具Retry

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 重试小工具Retry

该工具只是对Guava中Retryer拙劣的模仿。意在学习其Java8使用方式,代码解耦精髓。

package com.fast.cattsoft.util;

import java.util.concurrent.ExecutionException;

public interface RetryResult {

    boolean hasResult();

    boolean hasException();

    V getResult() throws IllegalAccessException;

    V get() throws ExecutionException;

    Throwable getException();

    int getRetryCount();


}
package com.fast.cattsoft.util;

public class SuccessRetryResult implements RetryResult {
    private R result;
    private int tryCount;
    private long intervaTime;

    public SuccessRetryResult(R result, int tryCount, long intervaTime) {
        this.result = result;
        this.tryCount = tryCount;
        this.intervaTime = intervaTime;
    }


    @Override
    public boolean hasResult() {
        return true;
    }

    @Override
    public boolean hasException() {
        return false;
    }

    @Override
    public R getResult() {
        return result;
    }

    @Override
    public R get() {
        return result;
    }

    @Override
    public Throwable getException() {
        return null;
    }

    @Override
    public int getRetryCount() {
        return 0;
    }
}
package com.fast.cattsoft.util;

import java.util.concurrent.ExecutionException;

public class ExceptionRetryResult implements RetryResult {
    private ExecutionException e;
    private int tryCount;
    private long intervaTime;

    ExceptionRetryResult(ExecutionException e, int tryCount, long intervaTime) {
        this.e = e;
        this.tryCount = tryCount;
        this.intervaTime = intervaTime;
    }

    @Override
    public boolean hasResult() {
        return false;
    }

    @Override
    public boolean hasException() {
        return true;
    }

    @Override
    public R getResult() throws IllegalAccessException {
        throw new IllegalAccessException("");
    }

    @Override
    public R get() throws ExecutionException {
        throw e;
    }

    @Override
    public Throwable getException() {
        return e.getCause();
    }

    @Override
    public int getRetryCount() {
        return tryCount;
    }
}
package com.fast.cattsoft.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;

public class RetryBuild {
    private List>> predicates =
            new ArrayList>>(Collections.singleton(new Predicate>() {
                @Override
                public boolean test(RetryResult vRetryResult) {
                    return false;
                }
            }));

    //重试次数
    private int tryCount = 1;

    //每次重试失败后间隔时间
    private long intervaTime = 1;

    public static  RetryBuild newBuild() {
        return new RetryBuild();
    }

    public RetryBuild buildTryCount(int tryCount) {
        this.tryCount = tryCount;
        return this;
    }

    public RetryBuild buildIntervaTime(long intervaTime) {
        this.intervaTime = intervaTime;
        return this;
    }

    public RetryBuild buildThrows(Class throwables) {
        predicates.add(new ExceptionClassPredicate(throwables));
        return this;
    }

    public RetryBuild buildResult(Predicate predicate) {
        predicates.add(new SuccessPredicate(predicate));
        return this;
    }

    public Retry build() {

        return new Retry(tryCount, intervaTime, new OnPredicate(predicates));
    }

}

class ExceptionClassPredicate implements Predicate> {
    private Class exception;

    public ExceptionClassPredicate(Class exception) {
        this.exception = exception;
    }

    @Override
    public boolean test(RetryResult vRetryResult) {
        if (!vRetryResult.hasException()) {
            return false;
        }
        return exception.isAssignableFrom(vRetryResult.getException().getClass());
    }
}

class SuccessPredicate implements Predicate> {
    private Predicate delegate;

    public SuccessPredicate(Predicate predicate) {
        this.delegate = predicate;
    }

    @Override
    public boolean test(RetryResult vRetryResult) {
        if (!vRetryResult.hasResult()) {
            return false;
        }
        try {
            V result = vRetryResult.getResult();
            boolean test = delegate.test(result);
            return test;
        } catch (Exception e) {
            throw new RuntimeException("");
        }
    }
}

class ExceptionPredicate implements Predicate> {
    private Predicate delegate;

    public ExceptionPredicate(Predicate delegate) {
        this.delegate = delegate;
    }

    @Override
    public boolean test(RetryResult vRetryResult) {
        if (!vRetryResult.hasException()) {
            return false;
        }
        return delegate.test(vRetryResult.getException());
    }
}

class OnPredicate implements Predicate> {

    //private List> predicates;
    private List>> predicates;

    public OnPredicate(List>> predicates) {
        this.predicates = predicates;
    }

    @Override
    public boolean test(RetryResult vRetryResult) {
        for (int i = 0; i < predicates.size(); i++) {
            if (predicates.get(i).test(vRetryResult)) {
                return true;
            }
        }
        return false;
    }
}


package com.fast.cattsoft.util;

import com.github.rholder.retry.*;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestClientException;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.function.Supplier;


public class Retry {

    //重试次数
    private int tryCount = 1;

    //每次重试失败后间隔时间
    private long intervaTime = 1;

    private Predicate> predicate;

    public Retry(int tryCount, long intervaTime, Predicate> predicate) {
        this.tryCount = tryCount;
        this.intervaTime = intervaTime;
        this.predicate = predicate;
    }


    public V call(Supplier supplier) throws ExecutionException {
        int currTryCount = 0;
        for (int i = 0; ; i++) {
            RetryResult retryResult;
            try {
                V result = supplier.get();
                retryResult = new SuccessRetryResult(result, tryCount, intervaTime);
            } catch (Exception e) {
                retryResult =
                        new ExceptionRetryResult(new ExecutionException(e), tryCount, intervaTime);
            } finally {
                currTryCount++;
            }

            if (!predicate.test(retryResult)) {
                return retryResult.get();
            }
            if (currTryCount >= this.tryCount) {
                throw new RuntimeException("retry number more than " + this.tryCount);
            } else {
                try {
                    Thread.sleep(this.intervaTime);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("");
                }
            }
        }
    }


    public static void main(String[] args) throws Throwable {
        customReTry();
        //guavaRetry();
    }

    public static void customReTry() throws Throwable {
        Retry build = RetryBuild.newBuild()
                .buildTryCount(3)
                .buildIntervaTime(2000l)
                .buildResult(res -> {
                    System.out.println("result has to than " + 6);
                    return res > 6;
                })
                .buildThrows(ArithmeticException.class)
                .build();
        Integer call = build.call(() -> {
            int i = 0;
            //int b = 4 / i;
            return 5;
        });
        System.out.println("result :" + call);

    }

    //可以参考guava重试代码
    public static void guavaRetry() throws ExecutionException, RetryException {
        new ArrayList<>(1);
        Retryer build = RetryerBuilder.newBuilder()
                //  .retryIfException(e -> e.getMessage().contains(""))
                .retryIfResult(e -> {
                    System.out.println("result has to than 5");
                    return e > 5;
                })
                .retryIfExceptionOfType(ArithmeticException.class)
                .withStopStrategy(StopStrategies.stopAfterAttempt(1))
                .withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS))
                .build();
        Integer call = build.call(() -> {
            int i = 0;
            //int b = 4 / i;
            return 5;
        });
        System.out.println("result :" + call);
    }

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/992590.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号