Releases: vapor/async-kit
Update Supported Swift Versions
This patch was authored and released by @0xTim.
This removes support for Swift 5.2 and Swift 5.3, making Swift 5.4 the earliest supported version as
announced
Removed file:line: from signature and code in Future+Try.swift
This patch was authored by @rjhancock and released by @gwynne.
removed due to depreciation warnings issued with latest Vapor.
Removes depreciated parameters file:line:
from method signature and calling method.
Add `EventLoop.performWithTask(_:)` to complement `EventLoopGroup.performWithTask(_:)`
This patch was authored and released by @gwynne.
Additional changes:
- Reimplement
EventLoopGroup.performWithTask(_:)
in terms ofEventLoop.performWithTask(_:)
. - Match implementations to NIO's code patterns for consistency.
- Major cleanup of AsyncKit source and tests layout (no functional changes).
- Better tests for the
performWithTask()
utilities; somehow we missed that it was originally implemented only on ELG and not EL, even though the exist test should have shown that by not even compiling successfully. - Improvements to the CI workflows to match latest advances.
Semver-minor release due to the addition of the missing public API.
adding `performWithTask` convenience func to convert async works to futures
This patch was authored by @MahdiBM and released by @gwynne.
This PR adds a convenience function to convert async works to futures, and reduces the need to directly use promises.
As an example, if you have the code below:
let promise = eventLoop.makePromise(of: SomeType.self)
promise.completeWithTask {
try await myAsyncFunc()
}
return promise.futureResult
It can be reduced to:
return eventLoop.performWithTask {
try await myAsyncFunc()
}
Submit Closure of .tryFuture to Event Loop Thread
This patch was authored and released by @calebkleveter.
Resolves #76
Add `EventLoopFuture.tryFlatMap()` by popular demand
This patch was authored by @vzsg and released by @0xTim.
One of the most common hurdles of working with EventLoopFutures, and a very oft-repeated question on the Discord server is interacting with error-throwing code. The tryFlatMap
extension alleviates that by handling any errors thrown by the closure, causing the ELF to fail.
This is the most common error handling pattern anyway.
Add EventLoopFuture utility methods for handling empty collection values
This patch was authored and released by @gwynne.
Provides:
EventLoopFuture.nonempty(orError:)
: If the future'sCollection
-conforming value is empty, fails the future with the provided error.EventLoopFuture.nonemptyMap(or:_:)
: If the future'sCollection
-conforming value is empty, returns the provided alternate value, otherwise acts like.map(_:)
.EventLoopFuture.nonemptyMap(_:)
: If the future'sCollection
-conforming value is empty, returns an empty instance of theRangeReplaceableCollection
-conforming result value, otherwise acts like.map(_:)
.EventLoopFuture.nonemptyFlatMapThrowing(or:_:)
: If the future'sCollection
-conforming value is empty, returns the provided alternate value, otherwise acts like.flatMapThrowing(_:)
.EventLoopFuture.nonemptyFlatMapThrowing(_:)
: If the future'sCollection
-conforming value is empty, returns an empty instance of theRangeReplaceableCollection
-conforming result value, otherwise acts like.flatMapThrowing(_:)
.EventLoopFuture.nonemptyFlatMap(or:_:)
: If the future'sCollection
-conforming value is empty, returns a future with the provided alternate value, otherwise acts like.flatMap(_:)
.EventLoopFuture.nonemptyFlatMap(orFlat:_:)
: If the future'sCollection
-conforming value is empty, returns the provided alternate future, otherwise acts like.flatMap(_:)
.EventLoopFuture.nonemptyFlatMap(_:)
: If the future'sCollection
-conforming value is empty, returns a future with an empty instance of theRangeReplaceableCollection
-conforming result value, otherwise acts like.flatMap(_:)
.
Example usage:
return MyModel.query(on: request.db)
.filter(\.foo == bar)
.all()
.nonempty(orError: Abort(.notFound))
.map { ...
return MyModel.query(on: request.db)
.filter(\.foo == bar)
.all()
.nonemptyMap { models -> [Something] in
...
Add some more `EventLoopFuture<Collection>` utilities.
This patch was authored and released by @gwynne.
I have to admit, everyone - this one's just a little bit for fun. But with Swift 5.5 and its concurrency magic around the corner, why not?! 😀
Changes:
- Add
EventLoopFuture.mapEachFlat(_:)
, shorthand forfuture.map { $0.flatMap(...) }
. Complements.mapEach(_:)
and.mapEachCompact(_:)
. Per the existing naming "convention", this is the "map a sequence of sequences to a sequence" utility, and.flatMapEach(_:)
is the "map a sequence to a sequence of futures" utility. It's not confusing at all! Totally!! - Add variants of
.mapEach(_:)
,.mapEachCompact(_:)
, and.mapEachFlat(_:)
which acceptKeyPath
s in place of transformation closures.
If you find yourself trying to articulate your argument against having these additions, you've already missed the point 🙂.
Add overload of flatMapEach(on:_:) for Void futures
This patch was authored and released by @gwynne.
This is effectively a convenience for using EventLoopFuture.andAllSucceed(_:on:)
.
Add `strictMap()` and `EventLoopFuture.whenTheySucceed()`
This patch was authored and released by @gwynne.
-
strictMap()
is a global function providing the services ofOptional.map()
for multiple optionals at once:strictMap(a, b, { foo($0, $1) })
is equivalent to (but slightly more efficient than)a.flatMap { a in b.map { b in foo(a, b) } }
. -
EventLoopFuture.whenTheySucceed()
provides the "wait for all to succeed or any to fail" semantics of.whenAllSucceed()
for a heterogenous set of futures. Or in other words, it's a more-than-two-futures version of.and()
:EventLoopFuture.whenTheySucceed(f1, f2, f3)
is equivalent to (but much more efficient than)f1.and(f2).and(f3).map { ($0.0, $0.1, $1) }
.