0

I have created a method that implements an async retry pattern. Actually, I want that when I call this method request should process in a separate thread and it should retry with some delay

private <R> CompletableFuture<R> withRetryRequest(Supplier<CompletableFuture<R>> supplier, int maxRetries) {
        CompletableFuture<R> f = supplier.get();
        for (int i = 0; i < maxRetries; i++) {
            f = f.thenApply(CompletableFuture::completedFuture)
                    .exceptionally(t -> {
                        try {
                            Thread.sleep(10 * 1000);
                        } catch (Exception exp) {
                            log.log(Level.SEVERE, "Error while delay executing", exp);
                        }
                        return supplier.get();
                    })
                    .thenCompose(Function.identity());
        }
        return f;
    }

here is a caller part:

ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(PropUtil.getPropUtil().THREAD_POOL_SIZE);

CompletableFuture<Boolean> retry = this.withRetryRequest(() -> runDoorOpenProcedure(req), req.getRetryCount());

final CompletableFuture<Boolean> retryFinal = retry;
CompletableFuture<CompletableFuture<Boolean>> retryRes = CompletableFuture.supplyAsync(() -> retryFinal, executor);
Boolean success = retry.get().join();

But it seems that call is not async at all. What I am doing wrong here, Can someone please have a look into this?

6
  • How do you know it's not called async? You have to do something between the CompletableFuture.supplyAsync and retry.get().join(), currently, your main thread is just waiting. Print something after the supplyAsync Commented May 6, 2020 at 6:10
  • Or you can print the thread_id inside the withRetryRequest. Thread currentThread = Thread.currentThread(); System.out.println("thread id:" + currentThread.getId()); Commented May 6, 2020 at 6:11
  • I have print the ThreadId in withRetryRequest and it seems to be the same thread for all the requests. "How do you know it's not called async?" I am calling this code from https request and every time HTTP call wait until retry complete so this is not async overall. I am not getting this where I am doing a mistake.
    – user565
    Commented May 6, 2020 at 6:24
  • I got your point. The reason your HTTP request is waiting because of you retry.get().join();. I think you need to find another way to write this logic, CompletedFuture not suitable for this scenario. Commented May 6, 2020 at 6:28
  • 1
    Every HTTP request works by sending the request and waiting for the result. To make it asynchronous, you would need a fundamental change in the setup, like scripts running in the browser to handle asynchronous results.
    – Holger
    Commented May 6, 2020 at 10:01

1 Answer 1

2

check this: https://winterbe.com/posts/2015/04/07/java8-concurrency-tutorial-thread-executor-examples/

CompletedFuture is suitable for some scenarios, such as you want to split your tasks into parallel and you still need the task result to continue or aggregate, then your main thread waits until you get all the results from all the subTasks. The main thread is blocked when subTasks are running.

If you don't need the results of the async tasks, you could create Thread and throw them into ThreadPool, then return.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.