Skip to content

Commit b51448d

Browse files
authored
Remove need for ActorQueueSynchronization (#40)
1 parent ef3c52d commit b51448d

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

Sources/AsyncQueue/ActorQueue.swift

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,26 @@ public final class ActorQueue<ActorType: Actor>: @unchecked Sendable {
6060
let (taskStream, taskStreamContinuation) = AsyncStream<ActorTask>.makeStream()
6161
self.taskStreamContinuation = taskStreamContinuation
6262

63-
Task { @ActorQueueSynchronization in
63+
func beginExecuting(
64+
_ operation: sending @escaping (isolated ActorType) async -> Void,
65+
in context: isolated ActorType
66+
) {
67+
// In Swift 6, a `Task` enqueued from an actor begins executing immediately on that actor.
68+
// Since we're running on our actor's context already, we can just dispatch a Task to get first-enqueued-first-start task execution.
69+
Task {
70+
await operation(context)
71+
}
72+
}
73+
74+
Task {
75+
// In an ideal world, we would isolate this `for await` loop to the `ActorType`.
76+
// However, there's no good way to do that without retaining the actor and creating a cycle.
6477
for await actorTask in taskStream {
65-
// In Swift 6, a `Task` enqueued from a global actor begins executing immediately on that global actor.
66-
// Since we're running on a global actor already, we can just dispatch a Task to get first-enqueued-first-start
67-
// task execution. In an ideal world, we wouldn't need a global actor and would isolate this `for await` loop on
68-
// the `ActorType`. However, there's no good way to do that just yet.
69-
Task {
70-
await actorTask.task(actorTask.executionContext)
71-
}
78+
// Await switching to the ActorType context.
79+
await beginExecuting(
80+
actorTask.task,
81+
in: actorTask.executionContext
82+
)
7283
}
7384
}
7485
}
@@ -152,10 +163,3 @@ public final class ActorQueue<ActorType: Actor>: @unchecked Sendable {
152163
let task: @Sendable (isolated ActorType) async -> Void
153164
}
154165
}
155-
156-
/// A global actor used for synchronizing task execution.
157-
@globalActor
158-
private struct ActorQueueSynchronization {
159-
fileprivate actor Synchronization {}
160-
fileprivate static let shared = Synchronization()
161-
}

0 commit comments

Comments
 (0)