28

I would like to know the general use case of using @Async and Servlet 3 asynchronous request implementation in Spring using Callable.

As I understand, @Async is for making any method (specifically, any service method) execute asynchronously.

@Async
void doSomething(String s) {
// this will be executed asynchronously
}

and any controller which returns Callable

  @RequestMapping("/view")
public Callable<String> callableWithView(final Model model) {
    return new Callable<String>() {
        @Override
        public String call() throws Exception {
            Thread.sleep(2000);
            model.addAttribute("foo", "bar");
            model.addAttribute("fruit", "apple");
            return "views/html";
        }
    };
}

I am confused on whento use what. What will be the effect of using Asynchronous servlet/controller and with spring @Async together?

Felipe
  • 3,986
  • 5
  • 29
  • 62
devThoughts
  • 770
  • 1
  • 10
  • 16

2 Answers2

24

This post has explanation for what you are looking for

Excerpt:

In some cases you can return to the client immediately while a background job completes processing. For example sending an email, kicking off a database job, and others represent fire-and-forget scenarios that can be handled with Spring's @Async support or by posting an event to a Spring Integration channel and then returning a confirmation id the client can use to query for the results.

Callable return type makes a controller method asynchronous. This is usually used in situations like long polling. Read this post by the same author for more information.

Also callable is an alternative for Runnable, in the sense, It can return results and throw checked exceptions.

Say you have a method

public String aMethod(){

}

This can be made asynchronous by simply returning a Callable interface.

public Callable<String>  aMethod(){

}
Paul Ratazzi
  • 5,881
  • 3
  • 33
  • 48
shazinltc
  • 3,406
  • 7
  • 29
  • 47
  • link to first post is broken – Chris Nov 11 '14 at 15:20
  • Hey thanks for letting me know. I have updated the link. Hope it helps. – shazinltc Nov 12 '14 at 05:20
  • @shazinltc if I needed to execute a task asynchronously and need to get a `taskId` right away (a `String` representing the registration of the task, something to help the user in keeping track of the task's progress), how can I achieve this given that the `taskId` must be generated in the method annotated with `@Async` and not by the invoker? – Web User Apr 03 '15 at 15:29
  • Its been almost two years since I have worked on this, so nothing on top of my head now. Very sorry for that. If I find time, I will look into it and get back to you. – shazinltc Apr 06 '15 at 09:10
  • @WebUser you need to generate the trackId before call the `@Async` and pass this trackId to the async method. This trackId can be a UUID, per example. – Dherik May 29 '18 at 14:18
  • Thanks @Dherik. That works as long as I have control of `trackId` generation. If another system generates it at the start of a process that is kicked off and returns that value to me, I guess I use the same principle. – Web User May 29 '18 at 14:27
0

you can not improve single request performance with using Callable interface, it helps to take more request in some cases. If your response type would be void, you can use runnable instead of callable, so with using runnable you can improve single request response time.

poyraz
  • 1