|
| 1 | +=== TimeLimiter |
| 2 | + |
| 3 | +==== Introduction |
| 4 | + |
| 5 | +The TimeLimiter API sets a time limit on the execution of a supplied future. The decorated supplied |
| 6 | +future can be chained with a CircuitBreaker to trip the circuit breaker if the supplied |
| 7 | +future's timeout has exceeded. |
| 8 | + |
| 9 | +The TimeLimiter provides the flexibility to handle custom future implementations such as ones that |
| 10 | +can cancel its execution gracefully. The TimeLimiter by default is configured to cancel the future |
| 11 | +if an exception occurs. This is configurable within the configuration. |
| 12 | + |
| 13 | +==== Examples |
| 14 | +[source,java] |
| 15 | +---- |
| 16 | +// For example, you want to restrict the execution of a long running task to 60 seconds. |
| 17 | +TimeLimiterConfig config = TimeLimiterConfig.custom() |
| 18 | + .timeoutDuration(Duration.ofSeconds(60)) |
| 19 | + .cancelRunningFuture(true) |
| 20 | + .build(); |
| 21 | +
|
| 22 | +// Create TimeLimiter |
| 23 | +TimeLimiter timeLimiter = TimeLimiter.of(config); |
| 24 | +---- |
| 25 | + |
| 26 | +===== Using a TimeLimiter |
| 27 | + |
| 28 | +TimeLimiter takes a Future Supplier and returns a Callable that will unwrap the Future and attempt |
| 29 | +to retrieve the future's value within the configured timeout period. If the timeout is reached, then |
| 30 | +an exception is thrown upstream and TimeLimiter, if configured, will attempt to cancel the future. |
| 31 | + |
| 32 | +[source,java] |
| 33 | +---- |
| 34 | +ExecutorService executorService = Executors.newSingleThreadExecutor(); |
| 35 | +
|
| 36 | +// Wrap your call to BackendService.doSomething() in a future provided by your executor |
| 37 | +Supplier<Future<Integer>> futureSupplier = () -> executorService.submit(backendService::doSomething) |
| 38 | +
|
| 39 | +// Decorate your supplier so that the future can be retrieved and executed upon |
| 40 | +Callable restrictedCall = TimeLimiter |
| 41 | + .decorateFutureSupplier(timeLimiter, futureSupplier); |
| 42 | +
|
| 43 | +Try.of(restrictedCall.call) |
| 44 | + .onFailure(throwable -> LOG.info("A timeout possibly occurred.")); |
| 45 | +---- |
| 46 | + |
| 47 | +===== TimeLimiter and CircuitBreaker |
| 48 | + |
| 49 | +The following example shows how to apply a timelimit to a circuit breaker callable. |
| 50 | + |
| 51 | +[source,java] |
| 52 | +---- |
| 53 | +Callable restrictedCall = TimeLimiter |
| 54 | + .decorateFutureSupplier(timeLimiter, futureSupplier); |
| 55 | +
|
| 56 | +// Decorate the restricted callable with a CircuitBreaker |
| 57 | +Callable chainedCallable = CircuitBreaker.decorateCallable(circuitBreaker, restrictedCall); |
| 58 | +
|
| 59 | +Try.of(chainedCallable::call) |
| 60 | + .onFailure(throwable -> LOG.info("We might have timed out or the circuit breaker has opened.")); |
| 61 | +---- |
0 commit comments