Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot REST API - request timeout?

I have a Spring Boot REST service that sometimes call third party services as a part of a request. I would like to set a timeout on all my resources (let's say 5 seconds), so that if any request handling (the whole chain, from incoming to response) takes longer than 5 seconds my controllers responds with HTTP 503 instead of the actual response. It would be awesome if this was just a Spring property, for example setting

spring.mvc.async.request-timeout=5000 

but I haven't had any luck with that. I've also tried extending WebMvcConfigurationSupport and overriding configureAsyncSupport:

@Override public void configureAsyncSupport(final AsyncSupportConfigurer configurer) {     configurer.setDefaultTimeout(5000);     configurer.registerCallableInterceptors(timeoutInterceptor()); }  @Bean public TimeoutCallableProcessingInterceptor timeoutInterceptor() {     return new TimeoutCallableProcessingInterceptor(); } 

without any luck.

I suspect I have to manually time all my third party calls, and if they take too long, throw a timeout exception. Is that right? Or is there any easier, holistic solution that covers all my request endpoints?

like image 871
Jesper N Avatar asked Jan 18 '16 10:01

Jesper N


People also ask

How do you implement timeout in REST API?

One way we can implement a request timeout on database calls is to take advantage of Spring's @Transactional annotation. It has a timeout property that we can set. The default value for this property is -1, which is equivalent to not having any timeout at all.

What is default connection timeout in spring boot?

connection-timeout=5000 in your application. properties. From the official documentation: server. connection-timeout= # Time in milliseconds that connectors will wait for another HTTP request before closing the connection.


2 Answers

You need to return a Callable<> if you want spring.mvc.async.request-timeout=5000 to work.

@RequestMapping(method = RequestMethod.GET) public Callable<String> getFoobar() throws InterruptedException {     return new Callable<String>() {         @Override         public String call() throws Exception {             Thread.sleep(8000); //this will cause a timeout             return "foobar";         }     }; } 
like image 67
Cyril Avatar answered Oct 02 '22 21:10

Cyril


The @Transactional annotation takes a timeout parameter where you can specify timeout in seconds for a specific method in the @RestController

@RequestMapping(value = "/method",     method = RequestMethod.POST,     produces = MediaType.APPLICATION_JSON_VALUE) @Timed @Transactional(timeout = 120) 
like image 38
fvorraa Avatar answered Oct 02 '22 21:10

fvorraa