Search code examples
spring-bootjava-8microservices

Microservice return response first and then process the request


I am working on a solution for which i am trying to create a microservice which returns response immediately and then processes the request.

I am trying to use Java 8 and Spring for this.


Solution

  • This can be achieved in several ways.

    In order to return a result from the current thread (a controller in this case) while still doing some long-running operation, you will need another thread.

    • Use Executor directly.

    A controller:

    @Controller
    public class AsyncController {
    
        private AsyncService asyncService;
    
        @Autowired
        public void setAsyncService(AsyncService asyncService) {
            this.asyncService = asyncService;
        }
    
        private ResponseEntity asyncMethod(@RequestBody Object request) {
            asyncService.process(new MyLongRunningRunnable());
    
            // returns immediately
            return ResponseEntity.ok("ok");
        }
    }
    

    And a service:

    @Service
    public class AsyncService {
        private ExecutorService executorService;
    
        @PostConstruct
        private void create() {
            executorService = Executors.newSingleThreadExecutor();
        }
    
        public void process(Runnable operation) {
            // no result operation
            executorService.submit(operation);
        }
    
    
        @PreDestroy
        private void destroy() {
            executorService.shutdown();
        }
    }
    

    More details can be found here https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

    • Another way is to use Spring built-in async capabilities

    You can simply annotate a method with @Async, having void or Future return type.

    If you still want to supply your own executor, you may implement AsyncConfigurer interface in your spring configuration bean. This approach also requires @EnableAsync annotation.

    @Configuration
    @EnableAsync
    public class AsyncConfiguration implements AsyncConfigurer {
    
        @Override
        public Executor getAsyncExecutor() {
            return Executors.newSingleThreadExecutor();
        }
    
    }
    

    More on this topic https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Async.html