7

I've been doing this tutorial about how to return async callable object. It works as intended. But while the first request sleeps for 5 seconds I get the second request, controller waits for the previous request to finnish before handling the second one.

How to make controller handle immediately every request and make sleeping in a background?

@Edit

Example: Imagine a situation, that my controller needs to make a request to external api and based on its response it should send his own response. External api call takes lets say 2 seconds. I want users of my application to wait only that 2,5 seconds and not be placed in queue, because the controller can handle only one request at a time.

1

2 Answers 2

16

Is REST controller multithreaded?

REST controller is multithreaded as the DisptcherServlet handles multiple requests from the clients concurrently and serves using the respective controller methods. You can refer the request handling flow here

How to make controller handle immediately every request and make sleeping in a background?

You can do that by returning Callable<String> in the Spring controller method as shown below:

@Controller
public class MyController {

    @RequestMapping(value="/sleep")
    public Callable<String> myControllerMethod() {
        Callable<String> asyncTask = () -> { try {
            System.out.println(" WAITING STARTED:"+new Date());
            Thread.sleep(5000);
            System.out.println(" WAITING COMPLETED:"+new Date());
            return "Return";//Send the result back to View Return.jsp
        } catch(InterruptedException iexe) {
            //log exception
            return "ReturnFail";
        }}; 
    return asyncTask;
  }

Output:

WAITING STARTED: Thu Nov 24 21:03:12 GMT 2016

WAITING COMPLETED: Thu Nov 24 21:03:17 GMT 2016

After this, the view will be returned "Return.jsp" page.

Here, the controller method will be running in a separate thread (releasing the actual servlet thread) and once the task is completed the Result will be sent back again to the client (View etc..).

P.S.: You need to add @EnableAsync as part of your application configuration, you can look here on this.

Sign up to request clarification or add additional context in comments.

5 Comments

I want to return a response after that 5 seconds, not immediately
I've already tried that, but when I send a request using POSTMAN the response comes right after (11ms). It doesn't wait at all
Did you add @EnableAsync ?
Yes I did, I created seperate configuration class
3

What you want to do is what it is supposed to be done in the first example of the tutorial you linked:

@RequestMapping(value = "/block", method = RequestMethod.GET, produces = "text/html")
public String executeSlowTask() {
    logger.info("Request received");
    Thread.sleep(5000);
    logger.info("Servlet thread released");

    return result;
}

This blocks the calling thread and waits till it is done. If you call from a different HTTP session, it will be another thread, so it will be a new 5 seconds wait (not affected by the first one).

Threads are linked to HTTP calls as long as there are threads available in the pool (configuration of the tomcat server).

It is not the case that the controller will block all subsequent calls while busy. It is multithreaded.

10 Comments

For me it blocks every incomming request
Then you have some sort of configuration issue. Are you in a virtual machine or another sort of restricted environment?
No, I am on my private computer with all admin rights
@Humberd Are you sure you tried requests from separate sessions? If you open different tabs on same browser they will share same session so same thread. Can you try from two different browsers?
The example is right. For me firstly I found that requests go sequentially - UNTIL I found that just to call an endpoint from different browser tabs is not enough for some reason I don't know why. So I move to Postman, and if you start requests from different tabs in it then you will have multithreading behaviour - the same as it will be in reality.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.