Повторите вызов функции n раз, когда функция выдает исключение в интервале времени y - PullRequest
0 голосов
/ 04 июня 2018

Я хотел повторить вызов функции каждый раз, когда происходит сбой в течение некоторого времени.Каков наилучший способ сделать это.Разве это будет работать нормально.

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);

1 Ответ

0 голосов
/ 04 июня 2018

Вы не должны помещать рабочий поток исполнителя в 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()) необходим, так как нет единого метода для объединения семантики handle и compose.

Обратите внимание, что начиная с Java 9, вы можете создать отложенного исполнителя так же просто, как

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

без необходимости иметь дело с ScheduledExecutorService самостоятельно.

...