Rest API request timeout

Viewed 918

I need to timeout my Rest Api when no response is returned. For example, when I make a request and if it takes more than 5 seconds to return a response, then Timeout.

In order to implement this, I opted for Circuit Breaker using Hystrix. But I am not sure whether it is the right way to approach this problem and if it's all good, should Hystrix be configured more?

My current implementation looks like,

Main class

@SpringBootApplication
@EnableCircuitBreaker
class MyApplication{

}

RestController

@GetMapping("/data")
@HystrixCommand(commandKey="response")
public String getResponse(){

    Thread.sleep(10000);
    .....
}

application.properties

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000

When timed out, it throws a HystrixRunTimeException and that's handled with a Custom Exception handler.

Is this the right approach to implement Request Timeout?

1 Answers

You may simply use a native CompletableFuture without need to add an external dependency for that:

CompletableFuture<String> task = CompletableFuture.supplyAsync(() -> {
    //your code which will return a String response at some point
});
try {
    return task.get(5, TimeUnit.SECONDS); //this will return if the future returns before 5 seconds, else will throw a timeout exception
} catch (InterruptedException | ExecutionException e) {
    //handle execution issues
} catch (TimeoutException e) {
    //you're called here if you timeout
}

The method CompletableFuture.supplyAsync() will asynchronously perform the task that makes you retrieve the String, hence it should contain your functional code. It should end with a return <your response>.

On the other hand, you get the future right after and the method .get(unit, timeoutUnit) will synchronously wait for the future to respond by the timeout.

In case of execution error (e.g. an exception is thrown in your functional code), you'll catch it inside the cause of ExecutionException.

In case of timeout (meaning the future is not complete by 5 seconds), you will catch a TimeoutException and will be able to respond whatever you wish to your caller.

There is also a possibility for InterruptedException, coming if the thread asynchronously performing the functional operation gets interrupted. I didn't treat that exception, you'll know better than me how you want to handle it.

Related