With Swift's structured concurrency, we can elegantly and seamlessly express correct asynchronous code.
Yet it is still non trivial to parallelise code execution in a way that is easy enough to be used by anyone, and that can scale relatively well between workloads and platforms. From a watch to a Linux server with 128 cores.
This library does not aim at bringing an asynchronous version of map
, forEach
and so forth. This aims at parallelising code execution in an asynchronous version of map
, forEach
….
It is Minimalist by essence, it only provides top level functions like map
and forEach
.
This package supports any first party Swift platform, from swift 5.7 and up. This is actually useful on Linux.
Well tested. Used in production across Infomaniak's apps written in Swift.
-
concurrentForEach
- Concurrently loops over a
Collection
to perform a task on each element. - Enumeration will stop if any error is thrown.
- Work will be executed out of order.
- Concurrently loops over a
-
concurrentMap
- Concurrently Maps a task with nullable result.
- Stops and throws at first error encountered.
- Work will be executed out of order.
- Input order preserved in the output result.
-
concurrentCompactMap
- Concurrently Maps a task to a collection of items, returning only non nil values.
- Stops and throws at first error encountered.
- Work will be executed out of order.
- Input order preserved in the output result.
-
asyncForEach
- Shorthand for
concurrentForEach(customConcurrency: 1)
- Serially loops over a
Collection
to perform an async task on each element.
- Shorthand for
-
asyncMap
- Shorthand for
concurrentMap(customConcurrency: 1)
- Serially Maps an async task with nullable result.
- Shorthand for
-
asyncCompactMap
- Shorthand for
concurrentCompactMap(customConcurrency: 1)
- Serially Maps an async task with nullable result, returning only non nil values
- Shorthand for
-
asyncReduce
- Serially reduce a collection with an async closure
An heuristic determines a degree of parallelism for you, but can be customised. We recommend sticking to a fixed parallelism (1-4ish) when working with network calls.
This runs right now in production code but will be refactored to be more in line with Swift 5.9 paradigms.
This do not use Task.yield()
. Implement yielding at your own discretion depending on your own workload.