-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add side effect callbacks during retry #106
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need the beforeEachAttempt
part, can't see any good use case for it. Users can simply enrich their retried effect with effectBefore >> myEffect
and retry such composite effect. Adding this to the retry API could the flow a bit confusing. The cats-retry
library offers a onError: (E, RetryDetails) => M[Unit]
callback, and I think we should be fine with a similar thing. Wdyt @rucek @DybekK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor coments, but overall LGTM.
afterEachAttemptInvoked shouldBe true | ||
afterEachAttemptInvocationCount shouldBe 1 | ||
returnedResult shouldBe Right(successfulResult) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't those assertions redundant? If you verify that the callback was invoked once, I guess one of them would be sufficient. Same for the "before" callback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onRetryInvoked shouldBe true
can be removed, since checking the invocation count would be sufficient enough.returnedResult shouldBe Right(successfulResult)
should not be removed. It checks whether the second parameter of theonRetry
function has been given the correct result, in this case,Right(successfulResult)
. If this assertion fails, it indicates that theonRetry
function wasn't given the correct result, and this oversight could potentially allow bugs to go unnoticed.
@tailrec | ||
def loop(attempt: Int, remainingAttempts: Option[Int], lastDelay: Option[FiniteDuration]): F[T] = | ||
def sleepIfNeeded = | ||
val delay = policy.schedule.nextDelay(attempt + 1, lastDelay).toMillis | ||
if (delay > 0) Thread.sleep(delay) | ||
delay | ||
|
||
lifecycle.beforeEachAttempt(attempt + 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we could just number the attempts starting from 1 instead of 0 - WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. In my opinion, it is more intuitive to read the code if we get rid of attempt + 1
in some places.
@kciesielski the difference would be that |
Yes, I'm aware of that difference, but I can't see the usefulness of this attempt number in such a case. I think we should choose a simpler API and sacrifice it. |
I completely removed |
Thanks! |
This PR addresses the proposed functionality in #56 and introduces enhancements to the retry mechanism by adding a
onRetry
function callback to theRetryPolicy
class.onRetry
callback is executed after each retry attempt. It accepts two parameters: the attempt number and the result of the attempt. The result is represented as an Either type, where Left indicates an error and Right indicates a successful result. By default, this is an empty function.