Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retry vs Delay #85

Open
AlessandroSteri opened this issue Mar 15, 2021 · 0 comments
Open

Retry vs Delay #85

AlessandroSteri opened this issue Mar 15, 2021 · 0 comments

Comments

@AlessandroSteri
Copy link

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 馃槃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant