Search code examples
javamultithreadingasynchronousunirest

How to send multiple asynchronous requests in parallel using Unirest


While using Unirest, the program doesn't exit until we manually shutdown every thread by invoking Unirest.shutdown(). If I had to make just one request, it's easy:

private static void asyncRequest (String link) {
    try {
        Future <HttpResponse <JsonNode>> request = Unirest.head(link).asJsonAsync(
                new Callback<JsonNode>() {
                    @Override
                    public void completed(HttpResponse<JsonNode> httpResponse) {
                        print(httpResponse.getHeaders());
                        try {
                            Unirest.shutdown();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void failed(UnirestException e) {
                        print(e.getMessage());
                    }

                    @Override
                    public void cancelled() {
                        print("Request cancelled");
                    }
                }
        );

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) throws Exception {
   asyncRequest("https://entrepreneur.com");
}

But I have to make multiple HTTP request in parallel (subsequent requests are meant not to wait for previous requests to complete). In the code above, I have to execute the code inside asyncRequest more than once with different links. The problem is I can't decide when to invoke Unirest.shutdown() so that the program exits as soon as the last request receives response. If I call Unirest.shutdown() after all the calls to asyncRequest in main, some or all the requests might get interrupted. If I call it inside completed (and other overridden methods), only the first request is made and others are interrupted. How can I solve this?


Solution

  • In theory, you could make the current thread wait for the execution of the method and after they are all done you can call the shutdown. But this would make the whole process synchronous, which is not what we want. So what I would do is, run different thread (other than the main one) which will wait for the execution of all your http requests. To do so you can use the class CountDownLatch, initializing with the countdown before it releases the control to the parent thread. You pass the instance of the CountDownLatch to the async method and you decrease by one each time you complete an http request. When it reaches 0 it returns the control to the parent thread, where you know you can call shutdown method as all your requests are done.