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

cn.acyou.leo.framework.util.WorkUtil Maven / Gradle / Ivy

package cn.acyou.leo.framework.util;

import cn.acyou.leo.framework.commons.AsyncManager;
import cn.acyou.leo.framework.constant.CommonErrorEnum;
import cn.acyou.leo.framework.exception.ServiceException;
import cn.acyou.leo.framework.util.function.CallTask;
import cn.acyou.leo.framework.util.function.Task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * 工作工具
 *
 * @author youfang
 * @version [1.0.0, 2022/3/31 14:55]
 **/
@Slf4j
public class WorkUtil {

    /**
     * 执行有返回值的任务,返回null则重试,非空则结束
     *
     * @param timeout  超时
     * @param unit     单位
     * @param supplier 供应商
     * @return {@link T}
     */
    public static  T doCallWork(long timeout, TimeUnit unit, Supplier supplier) {
        long startTime = System.nanoTime();
        long rem = unit.toNanos(timeout);
        do {
            try {
                T t = supplier.get();
                if (t != null) {
                    return t;
                }
            } catch (Exception ex) {
                if (rem > 0) {
                    try {
                        Thread.sleep(Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
                    } catch (Exception e) {
                        log.error(e.getMessage());
                        log.error(e.getMessage(), e);
                    }
                }
            }
            rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
        } while (rem > 0);
        return null;
    }


    /**
     * 执行忽略异常的任务
     *
     * @param task 任务
     */
    public static void tryRun(Task task) {
        try {
            task.run();
        } catch (Exception e) {
            printFirstStack(e);
        }
    }

    /**
     * 打印第一个栈信息
     *
     * @param e e
     */
    public static void printFirstStack(Throwable e) {
        String reason = e.getMessage();
        StackTraceElement[] stackTrace = e.getStackTrace();
        if (stackTrace != null && stackTrace.length > 0) {
            StackTraceElement stackTraceElement = stackTrace[0];
            reason = reason + " ERROR MSG: " + stackTraceElement.getClassName() + "|" + stackTraceElement.getMethodName() + ":" + stackTraceElement.getLineNumber();
        }
        log.error(reason);
    }

    /**
     * 尝试阻塞线程 5s
     */
    public static void trySleep5000() {
        trySleep(5000);
    }

    /**
     * 尝试阻塞线程
     *
     * @param millis 毫秒
     */
    public static void trySleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    /**
     * 重试工作
     *
     * @param times 次
     * @param task  任务
     * @return {@link T}
     */
    public static  T doRetryWork(int times, CallTask task) {
        int currentTime = 0;
        while (currentTime < times) {
            try {
                return task.run();
            } catch (Exception e) {
                log.error("doRetryWorkError 执行任务出错", e);
                currentTime++;
                trySleep(2000);
            }
        }
        return null;
    }

    /**
     * 重试工作
     *
     * @param times 次
     * @param task  任务
     */
    public static void doRetryWork(int times, Task task) {
        int currentTime = 0;
        while (currentTime < times) {
            try {
                task.run();
                return;
            } catch (Exception e) {
                log.error("doRetryWorkError 执行任务出错", e);
                currentTime++;
                trySleep(2000);
            }
        }
    }

    /**
     * 重试工作
     *
     * @param times 次
     * @param task  任务
     */
    public static void doRetryWorkGradually(int times, Task task) {
        doRetryWorkGradually(1, times, task);
    }
    /**
     * 重试工作
     *
     * @param times 次
     * @param task  任务
     */
    private static void doRetryWorkGradually(int currentTimes, int times, Task task) {
        AsyncManager.schedule(()->{
            if (currentTimes <= times) {
                try {
                    task.run();
                } catch (Exception e) {
                    log.error("doRetryWorkGradually 执行任务出错", e);
                    doRetryWorkGradually(currentTimes + 1, times, task);
                }
            }
        }, getGraduallyRule(currentTimes), TimeUnit.SECONDS);
    }

    private static int getGraduallyRule(int currentTimes){
        if (currentTimes <= 1) {
            return 1;
        }
        if (currentTimes == 2) {
            return 15;
        }
        if (currentTimes == 3) {
            return 15;
        }
        if (currentTimes == 4) {
            return 30;
        }
        if (currentTimes == 5) {
            return 3*60;
        }
        if (currentTimes == 6) {
            return 10*60;
        }
        return 10*60;
    }

    public static void watch(Task task) {
        StopWatch stopWatch = new StopWatch();
        log.info("任务耗时监控 开始 -> ...");
        stopWatch.start();
        task.run();
        stopWatch.stop();
        log.info("任务耗时监控 结束 <- 耗时:{}ms", stopWatch.getTotalTimeMillis());
    }

    public static  T doWaitWork(long waitTimeout, long interval, CallTask task) {
        final long deadline = System.currentTimeMillis() + waitTimeout;
        if (waitTimeout <= 0L) {
            return task.run();
        }
        try {
            do {
                T r = task.run();
                if (r != null) {
                    return r;
                }
                trySleep(Math.min(interval, deadline - System.currentTimeMillis()));
            } while (System.currentTimeMillis() < deadline);
        } catch (Exception e) {
            log.error("内部方法发生错误", e);
            return null;
        }
        throw new ServiceException(CommonErrorEnum.NO_WAIT_RESULT_ERROR);
    }

    /**
     * 吞并异常来执行 异常时返回NULL
     * @param callTask 有返回值
     * @return {@link T}
     */
    public static  T swallowException(CallTask callTask) {
        try {
            return callTask.run();
        }catch (Exception e) {
            printFirstStack(e);
            return null;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy