2

I am trying to handle the API rate limiting. I found that using ratelimiter I can block the usage of resources. Hence, in the following code I am trying to have only two threads until the batch (size) is completed processing.

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import com.google.common.util.concurrent.RateLimiter;

public class thenapply {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        List<Integer> list = Arrays.asList(1, 2, 3);
        final AtomicInteger sum = new AtomicInteger(0);
        final RateLimiter rateLimiter = RateLimiter.create(2.0); // rate is "2 permits per second"
        int size = list.size();
        CountDownLatch latch = new CountDownLatch(size);
        for (int i = 0; i < size; i++) {
            final int finali = i;
            rateLimiter.acquire(); // should wait till I get 2 requests
            CompletableFuture.runAsync(() -> {
                int sq= newdoc(list.get(finali));
                sum.addAndGet(sq);
                latch.countDown();
            });
        }
        latch.await();
        System.out.println(sum);
    }

    public static int newdoc(int val){
        return val*val;
    }
}
  1. In real time when we are trying to use the service, the end-user will be trying to call the service and if he calls it multiple times, we are throwing some error. How can we handle that using the delay. So basically, currently I have two requests using ratelimiter after that no request will be handled. how can I queue them with a delay?

  2. When will ratelimiter.acquire() be free to give resources? If after the processing of two requests, then what about my latch.countDown as it is after the for loop?

harry123
  • 760
  • 1
  • 7
  • 22
  • 1
    If you want to have two threads, then `RateLimiter` is the wrong tool -- you need an `Executor` with the right number of threads. – Louis Wasserman Oct 13 '20 at 23:36
  • @LouisWasserman can you please give an example of the solution? I am saying based on https://stackoverflow.com/questions/19819837/java-executor-with-throttling-throughput-control – harry123 Oct 14 '20 at 21:43
  • `Executor executor = Executors.newFixedThreadPool(2); CompletableFuture.runAsync(() -> { ... }, executor);` – Louis Wasserman Oct 14 '20 at 21:56
  • thanks @LouisWasserman. I am reading the threadpool. will this block 3rd request until the entire thread pool is free i.e. until request 1 and request 2 are completed? What if we want to send the 3rd request directly after the request 1 finishes even if request 2 is still running? – harry123 Oct 14 '20 at 23:08
  • It will run request 3 as soon as either one finishes. – Louis Wasserman Oct 15 '20 at 01:06
  • Thanks @LouisWasserman. I think that the above code doesn't guarantee us that there will be two request/second, right? If not how about using, `Executor delayed = CompletableFuture.delayedExecutor(0.5L, TimeUnit.SECONDS); CompletableFuture.supplyAsync(() -> {......}, delayed)` This will assure every request gets sent after 0.5s.How does that sound? – harry123 Oct 16 '20 at 19:20
  • Do you care about two requests per second, or two requests at a time? If the first one, RateLimiter. If the second one, Executor. – Louis Wasserman Oct 16 '20 at 19:47

0 Answers0