Skip to content

Commit ed8de67

Browse files
committed
Update ExecutionEvent.getStartTime to return Optional<Instant>.
1 parent 720fcf0 commit ed8de67

File tree

7 files changed

+40
-5
lines changed

7 files changed

+40
-5
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### API Changes
44

5-
- `ExecutionContext.getStartTime` now returns an `Instant` rather than a `Duration` object.
5+
- `ExecutionContext.getStartTime` now returns a `Instant` rather than `Duration`, and `ExecutionEvent.getStartTime` now returns `Optional<Instant>`.
66
- `getFailure`, `getLastFailure`, `recordFailure` and similar methods for recording Exceptions, which were previously deprecated, were removed. Use `getException`, `getLastException`, `recordException`, etc. instead.
77

88
# 3.2.4

core/src/main/java/dev/failsafe/ExecutionContext.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public interface ExecutionContext<R> {
7373
R getLastResult(R defaultValue);
7474

7575
/**
76-
* Returns the time that the initial execution started, else {code null} if an execution has not started yet.
76+
* Returns the time that the initial execution started.
7777
*/
7878
Instant getStartTime();
7979

core/src/main/java/dev/failsafe/event/ExecutionEvent.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import java.time.Duration;
2222
import java.time.Instant;
23+
import java.util.Optional;
2324

2425
/**
2526
* Encapsulates information about a Failsafe execution.
@@ -61,8 +62,8 @@ public int getExecutionCount() {
6162
/**
6263
* Returns the time that the initial execution started, else {code null} if an execution has not started yet.
6364
*/
64-
public Instant getStartTime() {
65-
return context.getStartTime();
65+
public Optional<Instant> getStartTime() {
66+
return Optional.ofNullable(context.getStartTime());
6667
}
6768

6869
/**

core/src/test/java/dev/failsafe/functional/BlockedExecutionTest.java

+31-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import dev.failsafe.*;
1919
import dev.failsafe.testing.Asserts;
2020
import dev.failsafe.testing.Testing;
21+
import net.jodah.concurrentunit.Waiter;
2122
import org.testng.annotations.Test;
2223

2324
import java.time.Duration;
@@ -30,7 +31,7 @@
3031
* Tests scenarios against a small threadpool where executions could be temporarily blocked.
3132
*/
3233
@Test
33-
public class BlockedExecutionTest {
34+
public class BlockedExecutionTest extends Testing {
3435
/**
3536
* Asserts that a scheduled execution that is blocked on a threadpool is properly cancelled when a timeout occurs.
3637
*/
@@ -49,6 +50,7 @@ public void shouldCancelScheduledExecutionOnTimeout() throws Throwable {
4950
TimeoutExceededException.class);
5051
Thread.sleep(300);
5152
assertFalse(supplierCalled.get());
53+
executor.shutdownNow();
5254
}
5355

5456
/**
@@ -70,6 +72,7 @@ public void shouldCancelScheduledRetryOnTimeout() {
7072

7173
Asserts.assertThrows(() -> future.get(500, TimeUnit.MILLISECONDS), ExecutionException.class,
7274
TimeoutExceededException.class);
75+
executor.shutdownNow();
7376
}
7477

7578
/**
@@ -93,6 +96,7 @@ public void shouldCancelScheduledFallbackOnTimeout() {
9396
Asserts.assertThrows(() -> future.get(500, TimeUnit.MILLISECONDS), ExecutionException.class,
9497
TimeoutExceededException.class);
9598
assertFalse(fallbackCalled.get());
99+
executor.shutdownNow();
96100
}
97101

98102
/**
@@ -117,5 +121,31 @@ public void shouldCancelScheduledFallbackOnCancel() throws Throwable {
117121
Asserts.assertThrows(future::get, CancellationException.class);
118122
Thread.sleep(300);
119123
assertFalse(fallbackCalled.get());
124+
executor.shutdownNow();
125+
}
126+
127+
/**
128+
* Asserts that start times are not populated in execution events for an execution that times out while blocked on a
129+
* thread pool, and never starts.
130+
*/
131+
public void shouldNotPopulateStartTime() throws Throwable {
132+
Waiter waiter = new Waiter();
133+
Timeout<Object> timeout = Timeout.builder(Duration.ofMillis(50)).withInterrupt().onFailure(e -> {
134+
waiter.assertTrue(!e.getStartTime().isPresent());
135+
}).build();
136+
ExecutorService executor = Executors.newFixedThreadPool(1);
137+
executor.execute(uncheck(() -> {
138+
Thread.sleep(500);
139+
}));
140+
141+
Failsafe.with(timeout).with(executor).onComplete(e -> {
142+
waiter.assertTrue(!e.getStartTime().isPresent());
143+
waiter.resume();
144+
}).runAsync(() -> {
145+
waiter.fail("Execution should not start due to timeout");
146+
});
147+
148+
waiter.await(1, TimeUnit.SECONDS);
149+
executor.shutdownNow();
120150
}
121151
}

core/src/test/java/dev/failsafe/issues/Issue231Test.java

+1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ public void shouldWaitForExecutionCompletion() {
3333
}
3434
}).get(), ExecutionException.class, TimeoutExceededException.class);
3535
assertTrue(executionCompleted.get());
36+
executorService.shutdownNow();
3637
}
3738
}

core/src/test/java/dev/failsafe/issues/Issue260Test.java

+1
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@ public void test() throws Throwable {
4242
f1.get(1, TimeUnit.SECONDS);
4343
f2.get(1, TimeUnit.SECONDS);
4444
f3.get(1, TimeUnit.SECONDS);
45+
executor.shutdownNow();
4546
}
4647
}

core/src/test/java/dev/failsafe/issues/Issue311Test.java

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import java.util.concurrent.CompletableFuture;
99
import java.util.concurrent.Executor;
10+
import java.util.concurrent.ExecutorService;
1011
import java.util.concurrent.Executors;
1112
import java.util.concurrent.atomic.AtomicInteger;
1213

@@ -25,6 +26,7 @@ public void failsafeFail() throws Throwable {
2526
})
2627
.get();
2728
assertEquals(counter.get(), 2);
29+
((ExecutorService) executor).shutdownNow();
2830
}
2931

3032
public void testNullCompletionStage() throws Throwable {

0 commit comments

Comments
 (0)