Luisao
Luisao

Reputation: 505

CompletableFuture grouped by groups of requests

I'd like to send 100K requests to an API Rest. So I have a loop and I send a request in a sync way (and it takes some minutes to complete all requests).

But it's better to send them in an async way, so the process can takes less time because the destination can scale their replicas.

I've read about CompletableFuture and how to combine all results with allOf() method.

But is there any way to make the calls in groups of 1K requests? Because If I send all the requests in parallel, the destination close the connection.

So I'd like to send request in group of 1K parallel request and when each group completes, do some stuff with the responses(I don't need the responses ordered)

Thanks.

Upvotes: 0

Views: 942

Answers (1)

Boris Chistov
Boris Chistov

Reputation: 950

Yep, you can use completable futures and its done pretty easy.

Let's suppose you have HTTP client that return CompletableFuture on requests.

package com.example.demo.cf;

import com.example.demo.dto.Response;

import java.util.concurrent.CompletableFuture;

public interface HttpClient {
    CompletableFuture<Response> makeHttp();
}

And have service that batchs and sequences requests.

package com.example.demo.cf;

import java.util.concurrent.CompletableFuture;
import java.util.stream.IntStream;

public class CfBatchingService {

    private static final int BATCH_SIZE = 100;

    private HttpClient httpClient;

    public void sendRequests() {
        CompletableFuture<Void> cf = CompletableFuture.completedFuture(null);
        for(int grp = 0; grp < 10; grp++) {
            cf = cf.thenCompose(unused -> CompletableFuture.allOf(IntStream.range(0, BATCH_SIZE).mapToObj(idx -> httpClient.makeHttp()).toArray(CompletableFuture[]::new)));
        }

        cf.whenComplete((unused, throwable) -> {
           System.out.println("All requested executed");
        });
    }

}

So, the only thing is needed here is to use thenCompose method, that expects to get CompletableFuture from lambda.

To group requests into batches and create single CompletableFuture you can use method CompletableFuture.allOf

Upvotes: 1

Related Questions