Async/await-based effects#27
Closed
gordonbrander wants to merge 5 commits into
Closed
Conversation
Collaborator
Author
|
One tradeoff with this approach is that we do want combine-like publisher-subscription semantics for things like subconsciousnetwork/subconscious#473 (comment). If we moved forward with this approach, we should still have an answer for how to support subscribing to combine publishers. |
Collaborator
Author
|
An alternative approach might be to continue to use combine publishers as our Fx mechanism, but create an extension that bridges async and Future. extension Future where Failure == Never {
convenience init(_ run: @escaping () async -> Output) {
self.init { promise in
Task {
let result = await run()
promise(.success(result))
}
}
}
}To limit the use of long-running effects, we could change the Fx type to |
Collaborator
Author
|
Closed in favor of #32 |
gordonbrander
added a commit
that referenced
this pull request
Apr 19, 2023
Introduces extensions to `Future` that allow you to create a Future from an async closure. This gives us a nice bridge from async swift to Combine. Also introduce other initializers for convenience, and to make dispatch un-ambiguous: `Update(state:fx:transaction:)` `Update(state:animation:)` `Update(state:fx:animation:)` Fixes #26 by bridging async/await to Combine. ## Notes on design and tradeoffs This PR is an alternative to #27. As mentioned in #27 (comment), there are tradeoffs with a pure async/await-based approach to Fx - We do want combine-like publisher-subscription semantics for things like subconsciousnetwork/subconscious#473 (comment). Therefore we would need combine publisher machinery in Store anyway. - Additionally, we need a way to batch fx. If we pursue a pure async/await based approach, leaves us carrying an array of async closures on Update. - Why? Because we want a collection of Action-producing asynchronous tasks/processes, all which are all run in parallel. - An async sequence is no good, because we need to resolve in parallel, not in sequence. - So that leaves us with an array of async closures, which are run in store. - However, this semantics essentially describes Publishers. Going with an array of async closures does little except lose us the affordances of Combine Publishers. One motivation for #26 was to have an explicit semantics of cancellation for long-polling tasks, by forcing them to fold into state via the update function at each step. This is good practice for the normal case. However, there are cases where this is not desired, like subconsciousnetwork/subconscious#473 (comment), or for keyboard events. Also, it is possible to cancel long-polling publishers at their source through the mechanisms publishers provide. There is no need for Store to have cancellation semantics. A reasonable approach forward is to stick with Publishers, but to make it very convenient to bridge from async swift to Publishers. In particular, we want to make it very convenient to produce `Future<Action, Never>`, since these are one-shot Fx that always succeed and never fail, so they have the desired property that you do one fx, which produces one action, then fold into state with update. And so, we introduce an extension to `Future` which allows you to create a Future from an async closure.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Instead of using Combine, we can take advantage of Swift's new concurrency primitives.
Fixes #26