-
Notifications
You must be signed in to change notification settings - Fork 6
Make delay cancelable #26
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
Comments
PS: I know that the docs say that |
Hi @julasamer, thanks for the issue! I'd have to double-check the source but I'm pretty sure the current implementation just pipes That said, this approach was primarily designed around the idea that any delay inherent in a promise is representative of actual work being done. But the After an admittedly brief amount of thought, here's 3 approaches I'm considering:
After outlining all this, I'm inclined to go ahead and do (1). |
I looked into the actual implementation. The current implementation does indeed just pipe the cancellation upwards. But more importantly, if the upstream promise does cancel, it still delays handling the cancelled result. By that I mean if you have something like Promise(result: .cancelled).delay(1) the delayed promise still waits 1 second before resolving to cancelled itself. I think preserving this behavior for upstream cancels is important for maintaining That said, the specific use-case you've described, of For your particular use-case I think a separate |
Filed as #27. |
Sounds reasonable. I guess, if I need a cancelable delay somewhere in my promise chain, I can do Thanks for being so responsive and looking into the issue! |
If you need to insert a cancellable delay somewhere in your promise chain, unfortunately what you just pasted won't actually work in the event that the upstream promise doesn't cancel. Even if the upstream promise does respond to cancels, there would still be a race where the upstream promise resolves, then you request cancel prior to the However, you can write your own wrapper that just immediately cancels the returned promise upon request but otherwise delegates to extension Promise {
func cancellableDelay(on context: PromiseContext = .auto, _ delay: TimeInterval) -> Promise {
return Promise(on: .immediate, { (resolver) in
let delayed = self.delay(on: context, delay).inspect(on:. immediate, { (result) in
resolver.resolve(with: result)
})
resolver.onCancelRequested(on: .immediate) { [upstream=delayed.cancellable] (resolver) in
resolver.cancel()
upstream.requestCancel()
}
})
}
} (note: I didn't actually test this, even for compilation) More generally, there might be a potential use for a |
I've filed #28 about |
This has been released in v0.4, along with |
The
delay
method is currently not cancelable. I.e., if arequestCancel
happens during the delay, the promise resolves successfully anyway:Expected outcome: Promise is resolved after 0.5s with a cancelled result. Actual result: Promise is fulfilled with
()
after the delay, cancel is ignored.I implemented another version in an extension that seems to do the job. The fact that the timer isn't actually cancelled is a little ugly though.
The text was updated successfully, but these errors were encountered: