Nitin
Nitin

Reputation: 81

Thread submit a task and do not wait for completion in spring

I am writing a service where I want to expose an endpoint which will call another service and if the service call is successful then I want to send back the result to UI/ calling app.

In parallel before sending back the response, I want to execute/submit a task which should run in background and my call should not be dependent on success or failure of this task.

Before returning the response i want to do the-

executorService.execute(object);

This should not be a blocking call..

Any suggestion

Upvotes: 2

Views: 5481

Answers (1)

Mark Bramnik
Mark Bramnik

Reputation: 42511

Spring Async methods is the way to go here as was suggested in comments.

Some caveats:

  1. Async methods can have different return types, its true that they can return CompletableFuture but this is in case if you called them from some background process and would like to wait/check for their execution status or perhaps, execute something else when the future is ready. In your case it seems that you want "fire-and-forget" behavior. So you should use void return type for your @Async annotated method.

  2. Make sure that you place @EnableAsync. Under that hood it works in a way that it wraps the bean that has @Async methods with some sort of proxy, so the proxy is actually injected into your service. So @EnableAsync turns on this proxy generation mechanism. You can verify that this is the case usually in the debugger and checking the actual type of the injected reference object.

  3. Consider customizing the the task executor to make sure that you're running the async methods with executor that matches your needs. For example, you won't probably want that every invocation of async method would spawn a new thread (and there is an executor that behaves like this). You can read about various executors here for example

Update

Code-wise you should do something like this:

public class MyAsyncHandler {

    @Async
    public void doAsyncJob(...) {
      ...
    }
}

@Service 
public class MyService {
  @Autowired // or autowired constructor
  private MyAsyncHandler asyncHandler;

  public Result doMyMainJob(params) {

     dao.saveInDB();
     // do other synchronous stuff
     Result res = prepareResult();
     asyncHandler.doAsyncJob(); // this returns immediately
     return res;
  }
}

Upvotes: 4

Related Questions