Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback, please email oracle-forums_moderators_us@oracle.com

CompletableFuture.whenComplete is not called for some Requests even after invoking the complete method

Rohit RajwaniMar 13 2024 — edited Mar 13 2024

Hi,

I am working on an application that relays the request to server asynchronously. For scenarios where multiple requests are sent per second,
I see that the CompletableFuture.whenComplete method is not being invoked for some of the requests even though all requests are getting success responses and it can be clearly seen that the complete method is called.

I am using jetty client to send the request to the server.

Call flow:
1. Client sends a request to my relay-application,
2. The controller catches it, creates a completable future with a couple of callbacks registered.
3. The request is sent for some processing afterwhich it is sent to the server, the process is asynchronous.
4. To make it non-blocking on the client side, the CompletableFuture is returned immediately.
5. After receiving the response from the server, the callback is called and which implicitly calls the "complete" method of the initial CompletableFuture.

Observations:
1. Ideally and for almost all the requests, the flow is normally executing.
2. For few of the requests, the whenComplete callback of the CompletableFuture is not called even after calling the "complete" method on it.

I am not sure what may be the cause of this, as the flow seems to be straight-forward and it is running fine for most of the requests.

Controller Method:

    @RequestMapping("/**")
    public CompletableFuture<ResponseEntity<?>>
    handleDownStreamReq(RequestEntity<byte[]> reqEntity, @RequestHeader HttpHeaders reqHeaders) {

        URI uri = null;
        try {
            uri = new URI(reqEntity.getUrl().toString());
        }
        catch (URISyntaxException ex) {
            System.out.println("Exception in forming URI, " + ex.toString());
        }
        byte[] body = reqEntity.getBody();

        CompletableFuture<ResponseEntity<?>> finalRspCompFuture = new CompletableFuture<>();

        // This method sends the request to the server asynchronously and
        // when the response is received the complete method on finalRspCompFuture is called
        buildAndSendRequest(uri, reqEntity, reqHeaders, body.length, body);

        finalRspCompFuture = finalRspCompFuture.exceptionally(ex->{

            ResponseEntity<byte[]> rsp = new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);

            return rsp;
        }).whenComplete((rsp, exe) -> {   // This whenComplete callback is not called even after finalRspCompFuture.complete()
            System.out.println("going in the when complete");
            if (exe != null) {
                System.out.println("whenComplete failed " + exe.toString());
            }
        });

        return finalRspCompFuture;
    }

Thanks!

Comments
Post Details
Added on Mar 13 2024
1 comment
101 views