Hydra
Hydra copied to clipboard
Retry vs Delay
Hi! First of all, I have to say that I really love this library 🙏
The reason for this issue is cause I'm not sure if I found a bug or if I misunderstood the semantics of retry
with delay.
Context
I was trying to implement polling to a web server leveraging Promises.
Say we have promise: Promise<Value>
which encapsulate the async call to our backend. Then I expressed polling with something like:
promise
.validate { value in /* predicate to decide if continue polling */ }
.retry(10, delay: pollingTime)
Expectation
Since:
-
validate
rejects the promise if the predicate is not met -
retry
allow to execute source chained promise if it ends with a rejection (exactly what I need, to re-issue the web call) -
delay
is the delay between each attempt (starting when failed the first time)
My expectation was to retry the promise at most 10 times, each with a delay of pollingTime
.
Result
AFAIU, the delay is implemented with the defer
which in turn defers only the happy path (then
) but the retryWhen
is actually targeting a rejected promise. This results in the delay being applied in the only attempt that succeeds (if any).
I've also tried to encapsulate the validate inside the promise (rejecting it if the predicate is not met) but it didn't move the problem.
I could achieve what I expected only pushing the validation inside the promise and implementing a deferAll
:
func `deferAll`(in context: Context = .background, _ seconds: TimeInterval) -> Promise<Value> {
guard seconds > 0 else { return self }
let fireTime: DispatchTime = .now() + seconds
return self
.then(in: context) { value in return Promise<Value> { resolve, _, _ in
context.queue.asyncAfter(deadline: fireTime) { resolve(value) }
}}
.recover { error in return Promise<Value> { _, reject, _ in
context.queue.asyncAfter(deadline: fireTime) { reject(error) }
}}
}
}
and leveraging it inside the retryWhen
in place of the defer
.
Am I misunderstanding the semantic of retry
with delay?
Thank you 😄