Skip to content

Commit 5afa45c

Browse files
committed
SE-0417: Remove leftovers that suggested actors ARE TaskExecutors
Leftover from initial draft; this is not being proposed.
1 parent b71c3d5 commit 5afa45c

File tree

1 file changed

+0
-57
lines changed

1 file changed

+0
-57
lines changed

proposals/0417-task-executor-preference.md

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -642,63 +642,6 @@ func function() async {
642642
}
643643
```
644644

645-
#### What about the Main Actor?
646-
647-
While the `MainActor` is not really special under this model, and behaves just as any other actor _with_ a specific executor requirement.
648-
649-
It is worth reminding that using the main actor's executor as a preferred executor would have the same effect as with any other executor. While usually using the main actor as preferred executor is not recommended. After all, this is why the original proposal was made to make nonisolated async functions hop *off* from their calling context, in order to free the main actor to interleave other work while other asynchronous work is happening.
650-
651-
In some situations, where the called asynchronous function may be expected to actually never suspend directly but only sometimes call another actor, and otherwise just return immediately without ever suspending. This may be used as fine optimization to tune around specific well known calls.
652-
653-
### Task executor preference and `AsyncSequence`s
654-
655-
One use-case worth calling out is AsyncSequences, especially when used from actors.
656-
657-
The following snippet illustrates a common performance pitfall today:
658-
659-
```swift
660-
actor Looper {
661-
func consumeSequence() async {
662-
for await value in getAsyncSequence() {
663-
// 1. hop-to global pool: await next()
664-
// 2. hop-to actor: execute for-loop body
665-
print("got: \(value)")
666-
}
667-
}
668-
}
669-
```
670-
671-
Because an async sequence's iterator has a nonisolated `next()` method (declared like this `func next() async -> Element?`),
672-
under the current execution semantics, the execution will _always_ hop to the global concurrent executor to execute the `next()` method,
673-
and only then let it run, potentially produce a value without even suspending (!), and hop back to the actor to process the body of the for-loop.
674-
675-
This is unfortunate and can cause a lot of back-and forth hopping that may not necessarily be desirable. Especially with async sequences which employ
676-
some form of buffering, such that e.g. the sequence has a number of elements "ready" and will return them immediately without having to suspend or synchronize with other `isolated` code.
677-
678-
With the use of task executor preference, we are able to circumvent the hops to the global concurrent executor, by preferring the actor's own executor, like this:
679-
680-
```swift
681-
actor Looper {
682-
func consumeSequence() async {
683-
withTaskExecutor(self) {
684-
for await value in getAsyncSequence() {
685-
// 1.a. 'next()' can execute on Looper's executor
686-
// 1.b. if next() needs to call some other isolated code, we would hop there
687-
// but only when necessary.
688-
// 2.a. Following the fast path where next() executed directly on Looper.executor,
689-
// the "hop back to actor" is efficient because it is a hop to the same executor which is a no-op.
690-
// 2.b. Following the slow path where next() had to call some `isolated` code,
691-
// the hop back to the Looper is the same as it would be normally.
692-
print("got: \(value)")
693-
}
694-
}
695-
}
696-
}
697-
```
698-
699-
Async sequences are expected to undergo further evolution in order to express isolation more efficiently in the actor case.
700-
Task executors are expected to fit well into this model, and offer an additional layer of "fine tuning" of developers encounter the need to do so.
701-
702645
## Prior-Art
703646

704647
It is worth comparing with other concurrency runtimes with similar concepts to make sure if there are some common ideas or something different other projects have researched.

0 commit comments

Comments
 (0)