I am relatively new to Spring Boot and started with the very simple example from their getting started site, which is (on the controller side):
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
What I want now, is that multiple (potentially long running) requests of the same controller can be served in parallel.
Since I already learned that a
Update: My bad: I thought it was related to the fact that the controller was a singleton. But true: Why should it not be able to run in parallel then?@RestController will be instantiated as singleton, it is clear for me, that multiple requests (which are handled by the same method) will be processed sequentially.
So I changed the example from above as follows so that a new instance of the controller is created on every request and with some means of inspecting what's actually happening:
@RestController
@Scope(value = "request")
public class HelloController {
private static AtomicInteger count = new AtomicInteger(0);
public HelloController() {
count.incrementAndGet();
}
@PostConstruct
public void init() {
System.out.println("start request " + count);
}
@PreDestroy
public void onDestroy() {
System.out.println("end request " + count);
}
@RequestMapping("/")
public String index() throws InterruptedException {
LocalDateTime now = LocalDateTime.now();
TimeUnit.SECONDS.sleep(15);
System.out.println(now);
return "Greetings from Spring Boot! " + now + " " + count.get();
}
}
Now I would expect to see that the requests are handled in parallel in about 15 seconds, but in fact I can only see that it is obviously processed sequentially and that it takes 30 seconds (on stdout):
start request 1
2017-02-11T14:19:47.429
end request 1
start request 2
2017-02-11T14:20:02.467
end request 2
So my question is: How can I achieve that such requests are processed in parallel since it is obviously not sufficient to create an instance for each request?
Little remark: I already tried using the @Asnync annotation in combination with @EnableAsync for the application class, but this seems to be a "fire and forget" such that I cannot get a response to show on the client side.
Several entries here on stackoverflow (eg. this and this) were interesting, but did not answer my question either, neither did this tutorial about asynchronous methods.
Update: Since several people pointed out that the issue may be related to the way I tested, I tried to run it with a different browser. Interestingly enough I experienced the same issues on Chrome as well as on Firefox. But when doing one request from each, it showed the expected behavior (serving the requests in parallel) – so I was fooled by the browers ...
You wrote:
Since I already learned that a @RestController will be instantiated as singleton, it is clear for me, that multiple requests (which are handled by the same method) will be processed sequentially.
"...will be processed sequentially" - this is false statement. I even have no idea on what basis it was made. Until you make method synchronized (or will use other lock technics), it will be accessible by multiple threads simultaneously.
In second case you've just configured it to create new instance for each request. I have only one idea explaining why do you receive sequential results in debugger: you perform this requests from browser sequentially as well.
If you want to test how multiply requests are perfectly handled even by 1st case, just open separate tabs in browser and start requests almost at the same time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With