Skip to content

Commit cad7507

Browse files
authored
Document withMainSerialExecutor caveats (#3)
* Add warning to README * wip
1 parent 35610e5 commit cad7507

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

README.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,16 @@ purpose, it has not landed in Swift.
156156

157157
Some asynchronous code is [notoriously difficult][reliably-testing-swift-concurrency] to test in
158158
Swift due to how suspension points are processed by the runtime. The library comes with a static
159-
function, `withMainSerialExecutor`, that runs all tasks spawned in an operation serially and
160-
deterministically. This function can be used to make asynchronous tests faster and less flakey.
159+
function, `withMainSerialExecutor`, that attempts to run all tasks spawned in an operation serially
160+
and deterministically. This function can be used to make asynchronous tests faster and less flakey.
161+
162+
> **Warning**: This API is only intended to be used from tests to make them more reliable. Please do
163+
> not use it from application code.
164+
>
165+
> We say that it "_attempts_ to run all tasks spawned in an operation serially and
166+
> deterministically" because under the hood it relies on a global, mutable variable in the Swift
167+
> runtime to do its job, and there are no scoping _guarantees_ should this mutable variable change
168+
> during the operation.
161169

162170
For example, consider the following seemingly simple model that makes a network request and manages
163171
so `isLoading` state while the request is inflight:

Sources/ConcurrencyExtras/MainSerialExecutor.swift

+11-3
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,24 @@
55
///
66
/// Some asynchronous code is [notoriously
77
/// difficult](https://forums.swift.org/t/reliably-testing-code-that-adopts-swift-concurrency/57304)
8-
/// to test in Swift due to how suspension points are processed by the runtime. This function runs
9-
/// all tasks spawned in the given operation serially and deterministically. It makes asynchronous
10-
/// tests faster and less flakey.
8+
/// to test in Swift due to how suspension points are processed by the runtime. This function
9+
/// attempts to run all tasks spawned in the given operation serially and deterministically. It
10+
/// makes asynchronous tests faster and less flakey.
1111
///
1212
/// ```swift
1313
/// await withMainSerialExecutor {
1414
/// // Everything performed in this scope is performed serially...
1515
/// }
1616
/// ```
1717
///
18+
/// > Warning: This API is only intended to be used from tests to make them more reliable. Please do
19+
/// > not use it from application code.
20+
/// >
21+
/// > We say that it "_attempts_ to run all tasks spawned in an operation serially and
22+
/// > deterministically" because under the hood it relies on a global, mutable variable in the Swift
23+
/// > runtime to do its job, and there are no scoping _guarantees_ should this mutable variable change
24+
/// > during the operation.
25+
///
1826
/// - Parameter operation: An operation to be performed on the main serial executor.
1927
@MainActor
2028
public func withMainSerialExecutor(

0 commit comments

Comments
 (0)