withExecutor causes Failsafe not to retry on exceptions in some cases
See original GitHub issueHey, thank you for this great library! I’ve got an issue to report however.
@Test
void failsafeFail() throws InterruptedException {
AtomicInteger counter = new AtomicInteger(0);
Executor executor = Executors.newSingleThreadExecutor();
Failsafe.with(RetryPolicy.builder()
.handle(RuntimeException.class)
.withMaxAttempts(2)
.build())
.with(executor)
.runAsync(() -> {
if (counter.incrementAndGet() == 1)
throw new RuntimeException();
});
Thread.sleep(100);
assertEquals(counter.get(), 2);
}
If you comment out .with(executor)
the test case will work. When the case fails the method is run from Functions.java#withExecutor(ContextualSupplier<R, T> supplier, Executor executor)
which calls handleExecutableThrowable
which just throws the exception again. With the line commented out it uses a different code path that actually handles the exception.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
Top Results From Across the Web
failsafe-lib/failsafe - Gitter
Hi, I was testing this library through a JUnit test case where there were two tasks in CompletableFuture.runAsync() and both fail after 2...
Read more >java - Failsafe RetryPolicy - throw exception from supplyAsync
I'm implementing a retry policy. Basically ...
Read more >Runtime Exceptions that are not in `retryOn` should ... - GitHub
I am confused by the fact that failsafe wraps RuntimeExceptions that are not specified for a retry. This leads to awkward unwrapping and ......
Read more >net.jodah.failsafe.RetryPolicy Java Exaples - ProgramCreek.com
This page shows Java code examples of net.jodah.failsafe.RetryPolicy. ... Create a retryable CompletableFuture Failsafe.with(retryPolicy).with(executor).
Read more >Retry Policy - Failsafe
Retry Policy. Attempts; Delays. Jitter. Duration; Aborts; Failure Handling; Event Listeners. Retry policies will retry failed executions a certain number of ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
How about adding those
instanceof
checks (forExecutorService
andScheduledExecutorService
) and also provide explicit config methodswithExecutor(Executor)
,withExecutorService(ExecutorService)
, andwithScheduler
(the latter could continue to be overloaded byScheduledExecutorService
andScheduler
)? Existing code usingwith
would do the right thing by avoiding unnecessary wrapping, and new code could be explicit about intent, allowing users to request wrapping even if unneeded. (For example, one might want to preserve the pre-instanceof
-check semantics ofwith
.)Explicit names are nice for those who read others’ code; they can skip that momentary confusion that occurs when encountering a line with no type information:
You can argue that
CONNECT_POOL
isn’t a great name, but it’s not an unrealistic one. I’d rather see this in that case:Maybe an explicit name like
withPlainExecutor(Executor)
would keep people from using that method accidentally.Amazing, thank you!