Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f46c7c7

Browse filesBrowse files
committed
Initial check in
1 parent e4d52aa commit f46c7c7
Copy full SHA for f46c7c7

File tree

Expand file treeCollapse file tree

5 files changed

+372
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+372
-0
lines changed
Open diff view settings
Collapse file

‎resilience4j/springboot-resilience4j/src/main/java/io/reflectoring/resilience4j/springboot/SpringbootResilience4jApplication.java‎

Copy file name to clipboardExpand all lines: resilience4j/springboot-resilience4j/src/main/java/io/reflectoring/resilience4j/springboot/SpringbootResilience4jApplication.java
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ public class SpringbootResilience4jApplication {
1414
@Autowired
1515
private RateLimiterExamplesRunner rateLimiterExamplesRunner;
1616

17+
@Autowired
18+
private TimeLimiterExamplesRunner timeLimiterExamplesRunner;
19+
1720
public static void main(String[] args) {
1821
SpringApplication.run(SpringbootResilience4jApplication.class, args);
1922
}
@@ -22,5 +25,6 @@ public static void main(String[] args) {
2225
public void runExamples() {
2326
retryExamplesRunner.run();
2427
rateLimiterExamplesRunner.run();
28+
timeLimiterExamplesRunner.run();
2529
}
2630
}
Collapse file
+142Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package io.reflectoring.resilience4j.springboot;
2+
3+
import io.reflectoring.resilience4j.springboot.model.Flight;
4+
import io.reflectoring.resilience4j.springboot.model.SearchRequest;
5+
import java.time.LocalDateTime;
6+
import java.time.format.DateTimeFormatter;
7+
import java.util.List;
8+
import java.util.concurrent.CompletableFuture;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.stereotype.Component;
11+
12+
@Component
13+
public class TimeLimiterExamplesRunner {
14+
15+
@Autowired
16+
private TimeLimitingService service;
17+
18+
private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss SSS");
19+
20+
public static void main(String[] args) {
21+
TimeLimiterExamplesRunner runner = new TimeLimiterExamplesRunner();
22+
runner.run();
23+
}
24+
25+
static void delay(int seconds) {
26+
// sleep to simulate delay
27+
try {
28+
Thread.sleep(seconds * 1000);
29+
} catch (InterruptedException e) {
30+
e.printStackTrace();
31+
}
32+
}
33+
34+
public void run() {
35+
System.out.println("Running timelimiter examples");
36+
37+
System.out.println(
38+
"----------------------- basicExample ----------------------------------------------------");
39+
basicExample();
40+
41+
delay(2); // delay just to let the above async operation to complete
42+
43+
System.out.println(
44+
"----------------------------------------------------------------------------------------------------");
45+
46+
System.out.println("----------------------- timeoutExample ----------------------------------------------");
47+
timeoutExample();
48+
49+
delay(2); // delay just to let the above async operation to complete
50+
51+
System.out.println("----------------------------------------------------------------------------------------------------");
52+
53+
System.out.println("----------------------- fallbackExample ----------------------------------------------");
54+
fallbackExample();
55+
56+
delay(2); // delay just to let the above async operation to complete
57+
58+
System.out.println("----------------------------------------------------------------------------------------------------");
59+
60+
System.out.println(
61+
"----------------------- eventsExample ----------------------------------------------------");
62+
eventsExample();
63+
delay(10); // delay just to let the above async operation to complete
64+
System.out.println(
65+
"----------------------------------------------------------------------------------------------------");
66+
}
67+
68+
private void eventsExample() {
69+
SearchRequest request = new SearchRequest("NYC", "LAX", "10/30/2021");
70+
for (int i = 0; i < 10; i++) {
71+
int attempt = i;
72+
service.eventsExample(request)
73+
.whenComplete((r, t) -> {
74+
if (t != null) {
75+
System.out.println("Error occurred on search " + attempt + ": " + t.getMessage());
76+
}
77+
if (r != null) {
78+
System.out
79+
.println("Search " + attempt + " successful, found " + r.size() + " flights");
80+
}
81+
});
82+
}
83+
}
84+
85+
private void timeoutExample() {
86+
SearchRequest request = new SearchRequest("NYC", "LAX", "10/30/2021");
87+
System.out.println("Calling search; current thread = " + Thread.currentThread().getName());
88+
CompletableFuture<List<Flight>> results = service.timeoutExample(request);
89+
results.whenComplete((result, ex) -> {
90+
if (ex != null) {
91+
System.out.println("Exception " +
92+
ex.getMessage() +
93+
" on thread " +
94+
Thread.currentThread().getName() +
95+
" at " +
96+
LocalDateTime.now().format(formatter));
97+
ex.printStackTrace();
98+
}
99+
if (result != null) {
100+
System.out.println(result + " on thread " + Thread.currentThread().getName());
101+
}
102+
});
103+
}
104+
105+
private void basicExample() {
106+
SearchRequest request = new SearchRequest("NYC", "LAX", "10/30/2021");
107+
System.out.println("Calling search; current thread = " + Thread.currentThread().getName());
108+
CompletableFuture<List<Flight>> results = service.basicExample(request);
109+
results.whenComplete((result, ex) -> {
110+
if (ex != null) {
111+
System.out.println("Exception " +
112+
ex.getMessage() +
113+
" on thread " +
114+
Thread.currentThread().getName() +
115+
" at " +
116+
LocalDateTime.now().format(formatter));
117+
}
118+
if (result != null) {
119+
System.out.println(result + " on thread " + Thread.currentThread().getName());
120+
}
121+
});
122+
}
123+
124+
private void fallbackExample() {
125+
SearchRequest request = new SearchRequest("NYC", "LAX", "10/30/2021");
126+
System.out.println("Calling search; current thread = " + Thread.currentThread().getName());
127+
CompletableFuture<List<Flight>> results = service.fallbackExample(request);
128+
results.whenComplete((result, ex) -> {
129+
if (ex != null) {
130+
System.out.println("Exception " +
131+
ex.getMessage() +
132+
" on thread " +
133+
Thread.currentThread().getName() +
134+
" at " +
135+
LocalDateTime.now().format(formatter));
136+
}
137+
if (result != null) {
138+
System.out.println(result + " on thread " + Thread.currentThread().getName());
139+
}
140+
});
141+
}
142+
}
Collapse file
+167Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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+
}
Collapse file

‎resilience4j/springboot-resilience4j/src/main/java/io/reflectoring/resilience4j/springboot/services/FlightSearchService.java‎

Copy file name to clipboardExpand all lines: resilience4j/springboot-resilience4j/src/main/java/io/reflectoring/resilience4j/springboot/services/FlightSearchService.java
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
import java.util.Arrays;
1414
import java.util.Collections;
1515
import java.util.List;
16+
import java.util.Random;
1617
import org.springframework.stereotype.Service;
1718

1819
@Service
1920
public class FlightSearchService {
2021

2122
PotentialFailure potentialFailure = new NoFailure();
2223
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss SSS");
24+
Random random = new Random();
2325

2426
PotentialFailureCheckedException potentialFailureCheckedException = new NoCheckedExceptionFailure();
2527

@@ -108,4 +110,42 @@ public SearchResponse httpSearchFlights(SearchRequest request) throws IOExceptio
108110
response.setFlights(flights);
109111
return response;
110112
}
113+
114+
public List<Flight> searchFlightsTakingOneSecond(SearchRequest request) {
115+
System.out.println("Searching for flights; "
116+
+ "current time = " + LocalDateTime.now().format(formatter) +
117+
"; current thread = " + Thread.currentThread().getName());
118+
119+
try {
120+
Thread.sleep(1000);
121+
} catch (InterruptedException e) {
122+
e.printStackTrace();
123+
}
124+
125+
List<Flight> flights = Arrays.asList(
126+
new Flight("XY 765", request.getFlightDate(), request.getFrom(), request.getTo()),
127+
new Flight("XY 746", request.getFlightDate(), request.getFrom(), request.getTo())
128+
);
129+
System.out.println("Flight search successful at " + LocalDateTime.now().format(formatter));
130+
return flights;
131+
}
132+
133+
public List<Flight> searchFlightsTakingRandomTime(SearchRequest request) {
134+
long delay = random.nextInt(3000);
135+
try {
136+
Thread.sleep(delay);
137+
} catch (InterruptedException e) {
138+
e.printStackTrace();
139+
}
140+
System.out.println("Searching for flights; "
141+
+ "current time = " + LocalDateTime.now().format(formatter) +
142+
"; current thread = " + Thread.currentThread().getName());
143+
144+
List<Flight> flights = Arrays.asList(
145+
new Flight("XY 765", request.getFlightDate(), request.getFrom(), request.getTo()),
146+
new Flight("XY 746", request.getFlightDate(), request.getFrom(), request.getTo())
147+
);
148+
System.out.println("Flight search successful");
149+
return flights;
150+
}
111151
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.