Skip to content

Commit b2f3ba8

Browse files
authored
BAEL-6091 structured concurrency (eugenp#13297)
1 parent 64060e8 commit b2f3ba8

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package com.baeldung.features;
2+
3+
import jdk.incubator.concurrent.StructuredTaskScope;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.time.Instant;
7+
import java.util.List;
8+
import java.util.concurrent.*;
9+
10+
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
11+
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
12+
13+
public class JEP428StructuredConcurrencyUnitTest {
14+
15+
private static final String ERROR_MESSAGE = "Failed to get the result";
16+
17+
@Test
18+
public void givenStructuredConcurrency_whenThrowingException_thenCorrect() {
19+
assertThatThrownBy(() -> {
20+
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
21+
Future<Shelter> shelter = scope.fork(this::getShelter);
22+
Future<List<Dog>> dogs = scope.fork(this::getDogsWithException);
23+
scope.throwIfFailed(e -> new RuntimeException(ERROR_MESSAGE));
24+
scope.join();
25+
Response response = new Response(shelter.resultNow(), dogs.resultNow());
26+
27+
assertThat(response).isNotNull();
28+
assertThat(response.shelter()).isNotNull();
29+
assertThat(response.dogs()).isNotNull();
30+
assertThat(response.dogs().size()).isEqualTo(2);
31+
}
32+
}).isInstanceOf(RuntimeException.class)
33+
.hasMessage(ERROR_MESSAGE);
34+
}
35+
36+
@Test
37+
public void givenStructuredConcurrency_whenSlowTasksReachesDeadline_thenCorrect() {
38+
assertThatThrownBy(() -> {
39+
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
40+
Future<Shelter> shelter = scope.fork(this::getShelter);
41+
Future<List<Dog>> dogs = scope.fork(this::getDogsSlowly);
42+
scope.throwIfFailed(e -> new RuntimeException(ERROR_MESSAGE));
43+
scope.join();
44+
scope.joinUntil(Instant.now().plusMillis(50));
45+
Response response = new Response(shelter.resultNow(), dogs.resultNow());
46+
47+
assertThat(response).isNotNull();
48+
assertThat(response.shelter()).isNotNull();
49+
assertThat(response.dogs()).isNotNull();
50+
assertThat(response.dogs().size()).isEqualTo(2);
51+
52+
} catch (InterruptedException e) {
53+
throw new RuntimeException(e);
54+
}
55+
}).isInstanceOf(IllegalStateException.class);
56+
}
57+
58+
@Test
59+
public void givenStructuredConcurrency_whenResultNow_thenCorrect() {
60+
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
61+
Future<Shelter> shelter = scope.fork(this::getShelter);
62+
Future<List<Dog>> dogs = scope.fork(this::getDogs);
63+
scope.join();
64+
65+
Response response = new Response(shelter.resultNow(), dogs.resultNow());
66+
67+
assertThat(response).isNotNull();
68+
assertThat(response.shelter()).isNotNull();
69+
assertThat(response.dogs()).isNotNull();
70+
assertThat(response.dogs().size()).isEqualTo(2);
71+
} catch (InterruptedException e) {
72+
throw new RuntimeException(e);
73+
}
74+
}
75+
76+
@Test
77+
public void givenUnstructuredConcurrency_whenGet_thenCorrect() {
78+
Future<Shelter> shelter;
79+
Future<List<Dog>> dogs;
80+
try (ExecutorService executorService = Executors.newFixedThreadPool(3)) {
81+
shelter = executorService.submit(this::getShelter);
82+
dogs = executorService.submit(this::getDogs);
83+
Shelter theShelter = shelter.get(); // Join the shelter
84+
List<Dog> theDogs = dogs.get(); // Join the dogs
85+
Response response = new Response(theShelter, theDogs);
86+
87+
assertThat(response).isNotNull();
88+
assertThat(response.shelter()).isNotNull();
89+
assertThat(response.dogs()).isNotNull();
90+
assertThat(response.dogs().size()).isEqualTo(2);
91+
92+
} catch (ExecutionException | InterruptedException e) {
93+
throw new RuntimeException(e);
94+
}
95+
}
96+
97+
private Shelter getShelter() {
98+
return new Shelter("Shelter");
99+
}
100+
101+
private List<Dog> getDogs() {
102+
return List.of(new Dog("Buddy"), new Dog("Simba"));
103+
}
104+
105+
private List<Dog> getDogsWithException() {
106+
throw new RuntimeException(ERROR_MESSAGE);
107+
}
108+
109+
private List<Dog> getDogsSlowly() throws InterruptedException {
110+
Thread.sleep(1500);
111+
throw new RuntimeException(ERROR_MESSAGE);
112+
}
113+
114+
record Shelter(String name) {
115+
}
116+
117+
record Dog(String name) {
118+
}
119+
120+
record Response(Shelter shelter, List<Dog> dogs) {
121+
}
122+
}

0 commit comments

Comments
 (0)