How to Set a Timeout on a Spring Boot Rest API

Spring Boot REST API - request timeout?

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";
}
};
}

Spring Boot Application - what is default timeout for any rest API endpoint or a easy config to control all endpoint timeout

I agree all above options and tried below option in my spring boot application. It works perfectly fine now. Below is the code sample as a bean. Now just need to @Autowire RestTemplate wherever(java class) I need it.

   @Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(15000);
((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setReadTimeout(15000);

return restTemplate;
}

Best way to limit time execution in a @RestController

What I managed to do, but I don't know if there are any conceptual or practical flaws is what it follows...

First, the configuration of spring-async

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

@Bean(name = "threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {

ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(10);
pool.setMaxPoolSize(10);
pool.setWaitForTasksToCompleteOnShutdown(true);
return pool;
}

@Override
public Executor getAsyncExecutor() {
return new SimpleAsyncTaskExecutor();
}
}

And next, the Controller and Service modifications:

@RestController
@RequestMapping("/timeout")
public class TestController {

@Autowired
private TestService service;

@GetMapping("/max10secs")
public String max10secs() throws InterruptedException, ExecutionException {
Future<String> futureResponse = service.call();
try {
//gives 10 seconds to finish the methods execution
return futureResponse.get(10, TimeUnit.SECONDS);
} catch (TimeoutException te) {
//in case it takes longer we cancel the request and check if the method is not done
if (futureResponse.cancel(true) || !futureResponse.isDone())
throw new TestTimeoutException();
else {
return futureResponse.get();
}
}
}
}

@Service
public class TestService {

@Async("threadPoolTaskExecutor")
public Future<String> call() {
try{
//some business logic here
return new AsyncResult<>(response);
} catch (Exception e) {
//some cancel/rollback logic when the request is cancelled
return null;
}
}
}

And finally generate the TestTimeoutException:

@ResponseStatus(value = HttpStatus.REQUEST_TIMEOUT, reason = "too much time")
public class TestTimeoutException extends RuntimeException{ }


Related Topics



Leave a reply



Submit