'Is this possible to apply bucketisation in Spring Boot (TOMCAT)

I exposed 2 api's

/endpoint/A and /endpoint/B .

@GetMapping("/endpoint/A")
    public ResponseEntity<ResponseA> controllerA() throws InterruptedException {

        ResponseA responseA = serviceA.responseClient();
        return ResponseEntity.ok().body(responseA);
    }



@GetMapping("/endpoint/B")
    public ResponseEntity<ResponseA> controllerB() throws InterruptedException {

        ResponseA responseB = serviceB.responseClient();
        return ResponseEntity.ok().body(responseB);
    }

Services implemented regarding endpoint A internally call /endpoint/C and endpoint B internally call /endpoint/D.

As external service /endpoint/D taking more time i.e getting response from /endpoint/A takes more time hence whole threads are stucked that is affecting /endpoint/B.
I tried to solve this using executor service having following implementation

@Bean(name = "serviceAExecutor")
    public ThreadPoolTaskExecutor serviceAExecutor(){

        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(100);
        taskExecutor.setMaxPoolSize(120);
        taskExecutor.setQueueCapacity(50);
        taskExecutor.setKeepAliveSeconds(120);
        taskExecutor.setThreadNamePrefix("serviceAExecutor");
        return taskExecutor;
    }

Even after implementing this if I received more than 200 request on /endpoint/A simultaneously (greater than default max number of threads in Tomcat server) then I am not getting responses from /endpoint/B as all threads are busy for getting response from endpoint A or in queue.

Can someone plz suggest is there any way to apply bucketization on each exposed endpoint level and allow only limited request to process at a time & put remaining into bucket/queue so that request on other endpoints can work properly ?

Edit:- following is solution approach

@GetMapping("/endpoint/A")
        public CompletableFuture<ResponseEntity<ResponseA>> controllerA() throws InterruptedException {
    
            return CompletableFuture.supplyAsync(()->controllerHelperA());
        }



    @GetMapping("/endpoint/B")
        public CompletableFuture<ResponseEntity<ResponseB>> controllerB() throws InterruptedException {
    
            return CompletableFuture.supplyAsync(()->controllerHelperB());
        }

private ResponseEntity<ResponseA> controllerHelperA(){

        ResponseA responseA = serviceA.responseClient();
        return ResponseEntity.ok().body(responseA);
    }

private ResponseEntity<ResponseB> controllerHelperB(){

        ResponseB responseB = serviceB.responseClient();
        return ResponseEntity.ok().body(responseB);
    }


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source