vapor / async-kit

Sugary extensions for the SwiftNIO library
MIT License
71 stars 25 forks source link

[Proposal] `whenAllComplete` Method to Flatten Array of Futures Without Failure #12

Closed Mordil closed 5 years ago

Mordil commented 5 years ago

I've seen this requested a few times in the Vapor Discord, and I've wanted this myself for awhile (before I wrote a local implementation).

As it stands

Vapor's Core extension of flatten and syncFlatten takes an array of Future<Void> and flattens them into a single Future<Void> that either succeeds when all Futures in the array succeed, or fails as soon as one fails.

That is useful on its own, but some times there are cases where you need to batch run tasks (like make multiple API requests based on an array of parameters) that you then want to handle each case individually and independently.

My exact use case is where I am synchronizing a database cache of Slack user data, and I need to make 100+ individual profile requests, but I only care about:

1) Each individual request response, to save the appropriate data to the database 2) When all of the requests have completed, even if they failed.

Proposal

1) Introduce a whenAllComplete method to EventLoop that always resolves when all of the EventLoopFutures in a collection complete (failure or success).

extension EventLoop {
    public func whenAllComplete<T>(_ futures: [EventLoopFuture<T>]) -> EventLoopFuture<[Result<T, Error>]>

    public func whenAllComplete<T>(_ futures: [EventLoopFuture<T>]) -> EventLoopFuture<Void>
}
Mordil commented 5 years ago

After spending some time in the NIO layer and spending some time on implementing this, I've learned some things and have updated the proposal:

1) syncAll only really applies to a handful of specific instances in all of Vapor's codebase and is not widely needed as it doesn't actually force the futures to be synchronous with each other. 2) Result can be used instead of nil values as that has landed in Swift 5 3) all has been renamed to whenAllComplete to match the NIO methods whenSuccess, whenFailure, and whenComplete

Mordil commented 5 years ago

Closing this, as SwiftNIO has welcomed these additions to their library