java - 当函数在 y 时间间隔内抛出异常时,重试函数调用 n 次

标签 java java-8 scheduled-tasks schedule retry-logic

每当我的函数调用在一段时间内失败时,我想重试它。 最好的方法是什么? 这可以正常工作吗?

CompletableFuture.runAsync(() -> {
    for (int i = 0; i < 3; i++) {
        try {
            dndService.initateDNDRequest(transactionId, circle, category, "PREPAID");       
            break;
        } catch (Exception e) {
            try {
                TimeUnit.SECONDS.sleep(10);//wait for few minutes while next attempt
            } catch (InterruptedException e1) {
                LOGGER.error("Error while retrying request for DND.");
            }
            LOGGER.error("Request retry for DND count"+i);
        }
    }
}, executor);

最佳答案

您不应将执行程序的工作线程置于 sleep 状态。

安排新尝试的一个解决方案是

    Executor executor; // … the actual executor
    ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
    Executor afterTenSeconds
        = r -> ses.schedule(() -> executor.execute(r), 10, TimeUnit.SECONDS);

    Runnable primaryAction
        = () -> dndService.initateDNDRequest(transactionId, circle, category, "PREPAID");

    CompletableFuture<Void> cf = CompletableFuture.runAsync(primaryAction, executor);
    for(int i = 0; i < 3; i++) {
        cf = cf.handle((v,t) -> t == null? CompletableFuture.completedFuture(v):
                                CompletableFuture.runAsync(primaryAction, afterTenSeconds))
               .thenCompose(Function.identity());
    }

然后,handle 操作将安排一次新的尝试,在失败情况下超时(十秒)后执行。 thenCompose(Function.identity()) 是必要的,因为没有单一方法可以组合 handlecompose 语义。

请注意,从 Java 9 开始,您可以像下面这样简单地创建延迟执行器

Executor afterTenSeconds = CompletableFuture.delayedExecutor(10,TimeUnit.SECONDS,executor);

无需自己处理ScheduledExecutorService

关于java - 当函数在 y 时间间隔内抛出异常时,重试函数调用 n 次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50679825/

相关文章:

java - Character.getNumericValue() 问题

java - 从 COM 到 MySql 的串行输入

java - Activiti Explorer - 请求资源不可用

Facebook 应用 : scheduling a task

java - 如何自动运行maven命令,而不是通过命令?

java - Oracle 10g 中使用哪种数据类型来存储 DateTime?

java - 您可以从子类化该接口(interface)的接口(interface)调用父接口(interface)的默认方法吗?

java - +0 和 -0 显示 int 和 float 数据的不同行为

c# - WP7-8 periodicTask启动时调用mainPage中任意方法

scheduled-tasks - Powershell 4 Get-ScheduledTask 和 Windows