1+ package io .reflectoring .resilience4j .springboot ;
2+
3+ import io .github .resilience4j .micrometer .tagged .TaggedTimeLimiterMetrics ;
4+ import io .github .resilience4j .ratelimiter .RequestNotPermitted ;
5+ import io .github .resilience4j .ratelimiter .annotation .RateLimiter ;
6+ import io .github .resilience4j .timelimiter .TimeLimiter .EventPublisher ;
7+ import io .github .resilience4j .timelimiter .TimeLimiterConfig ;
8+ import io .github .resilience4j .timelimiter .TimeLimiterRegistry ;
9+ import io .github .resilience4j .timelimiter .annotation .TimeLimiter ;
10+ import io .micrometer .core .instrument .Measurement ;
11+ import io .micrometer .core .instrument .Meter ;
12+ import io .micrometer .core .instrument .MeterRegistry ;
13+ import io .micrometer .core .instrument .simple .SimpleMeterRegistry ;
14+ import io .reflectoring .resilience4j .springboot .model .Flight ;
15+ import io .reflectoring .resilience4j .springboot .model .SearchRequest ;
16+ import io .reflectoring .resilience4j .springboot .services .FlightSearchService ;
17+ import java .sql .Time ;
18+ import java .time .Duration ;
19+ import java .time .LocalDateTime ;
20+ import java .util .ArrayList ;
21+ import java .util .Arrays ;
22+ import java .util .List ;
23+ import java .util .concurrent .CompletableFuture ;
24+ import java .util .concurrent .CompletionStage ;
25+ import java .util .concurrent .ExecutionException ;
26+ import java .util .concurrent .Executors ;
27+ import java .util .concurrent .ScheduledExecutorService ;
28+ import java .util .concurrent .TimeUnit ;
29+ import java .util .concurrent .TimeoutException ;
30+ import java .util .function .Consumer ;
31+ import java .util .function .Supplier ;
32+ import java .util .stream .StreamSupport ;
33+ import javax .annotation .PostConstruct ;
34+ import org .springframework .beans .factory .annotation .Autowired ;
35+ import org .springframework .stereotype .Service ;
36+
37+ @ Service
38+ public class TimeLimitingService {
39+ @ Autowired
40+ private FlightSearchService remoteSearchService ;
41+
42+ @ Autowired
43+ private TimeLimiterRegistry timeLimiterRegistry ;
44+
45+ /*
46+ void printDefaultValues() {
47+ TimeLimiterConfig config = TimeLimiterConfig.ofDefaults();
48+
49+ System.out.println(
50+ "getTimeoutDuration in ms = " + Duration.from(config.getTimeoutDuration()).toMillis());
51+ System.out.println("shouldCancelRunningFuture = " + config.shouldCancelRunningFuture());
52+ } */
53+
54+
55+ @ TimeLimiter (name = "basicExample" )
56+ CompletableFuture <List <Flight >> basicExample (SearchRequest request ) {
57+ return CompletableFuture .supplyAsync (() -> remoteSearchService .searchFlightsTakingOneSecond (request ));
58+ }
59+
60+ @ TimeLimiter (name = "timeoutExample" )
61+ CompletableFuture <List <Flight >> timeoutExample (SearchRequest request ) {
62+ return CompletableFuture .supplyAsync (() -> remoteSearchService .searchFlightsTakingOneSecond (request ));
63+ }
64+
65+ @ TimeLimiter (name = "timeAndRateLimiter" )
66+ @ RateLimiter (name = "timeAndRateLimiter" )
67+ CompletableFuture <List <Flight >> aspectOrderExample (SearchRequest request ) {
68+ return CompletableFuture .supplyAsync (() -> remoteSearchService .searchFlightsTakingOneSecond (request ));
69+ }
70+
71+ /*
72+ void basicExample_ExcecuteCompletionStage() {
73+ TimeLimiterConfig config = TimeLimiterConfig.custom()
74+ .timeoutDuration(Duration.ofMillis(500))
75+ .build();
76+
77+ TimeLimiterRegistry registry = TimeLimiterRegistry.of(config);
78+ TimeLimiter limiter = registry.timeLimiter("flightSearch");
79+
80+ FlightSearchService service = new FlightSearchService();
81+ SearchRequest request = new SearchRequest("NYC", "LAX", "08/30/2020");
82+
83+ Supplier<List<Flight>> flightSupplier = () -> service.searchFlightsTakingOneSecond(request);
84+ Supplier<CompletionStage<List<Flight>>> origCompletionStageSupplier = () -> CompletableFuture
85+ .supplyAsync(flightSupplier);
86+ ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
87+ CompletionStage<List<Flight>> decoratedCompletionStage = limiter
88+ .executeCompletionStage(scheduler, origCompletionStageSupplier);
89+
90+ decoratedCompletionStage.whenComplete((result, ex) -> {
91+ if (ex != null) {
92+ System.out.println("Exception " +
93+ ex.getMessage() +
94+ " on thread " +
95+ Thread.currentThread().getName() +
96+ " at " +
97+ LocalDateTime.now().format(formatter));
98+ }
99+ if (result != null) {
100+ System.out.println(result + " on thread " + Thread.currentThread().getName());
101+ }
102+ });
103+
104+ scheduler.shutdown();
105+ }
106+
107+
108+ void whenToUseExample() {
109+ CompletableFuture.supplyAsync(this::slowMethod).thenAccept(System.out::println);
110+ }
111+
112+ void whenToUseExample_Blocking()
113+ throws InterruptedException, ExecutionException, TimeoutException {
114+ CompletableFuture<Integer> completableFuture = CompletableFuture
115+ .supplyAsync(this::slowMethod);
116+ Integer result = completableFuture.get(3000, TimeUnit.MILLISECONDS);
117+ System.out.println(result);
118+ }
119+
120+ int slowMethod() {
121+ System.out.println(Thread.currentThread().getName());
122+ // sleep to simulate delay
123+ try {
124+ Thread.sleep(2000);
125+ } catch (InterruptedException e) {
126+ e.printStackTrace();
127+ }
128+ return 0;
129+ }
130+
131+ static void delay(int seconds) {
132+ // sleep to simulate delay
133+ try {
134+ Thread.sleep(seconds * 1000);
135+ } catch (InterruptedException e) {
136+ e.printStackTrace();
137+ }
138+ } */
139+
140+ @ TimeLimiter (name = "eventsExample" )
141+ CompletableFuture <List <Flight >> eventsExample (SearchRequest request ) {
142+ return CompletableFuture .supplyAsync (() -> remoteSearchService .searchFlightsTakingRandomTime (request ));
143+ }
144+
145+ @ TimeLimiter (name = "fallbackExample" , fallbackMethod = "localCacheFlightSearch" )
146+ CompletableFuture <List <Flight >> fallbackExample (SearchRequest request ) {
147+ return CompletableFuture .supplyAsync (() -> remoteSearchService .searchFlightsTakingOneSecond (request ));
148+ }
149+
150+ private CompletableFuture <List <Flight >> localCacheFlightSearch (SearchRequest request , TimeoutException rnp ) {
151+ System .out .println ("Returning search results from cache" );
152+ System .out .println (rnp .getMessage ());
153+ CompletableFuture <List <Flight >> result = new CompletableFuture <>();
154+ result .complete (Arrays .asList (
155+ new Flight ("XY 765" , request .getFlightDate (), request .getFrom (), request .getTo ()),
156+ new Flight ("XY 781" , request .getFlightDate (), request .getFrom (), request .getTo ())));
157+ return result ;
158+ }
159+
160+ @ PostConstruct
161+ void postConstruct () {
162+ EventPublisher eventPublisher = timeLimiterRegistry .timeLimiter ("eventsExample" ).getEventPublisher ();
163+ eventPublisher .onSuccess (System .out ::println );
164+ eventPublisher .onError (System .out ::println );
165+ eventPublisher .onTimeout (System .out ::println );
166+ }
167+ }
0 commit comments