I've looked through just about every question on this topic I could find but I've had little success. I need to run a function on an array of actors conforming to a specific actor protocol. Because these are actors, I need an async call. But I also need to run these functions in a specific order, and I'm not going to describe how I get the order, just suffice it to say that I have it. I am also using the following asyncForEach
function, though I'm open to not doing this.
extension Sequence {
func asyncForEach (
_ operation: @escaping (Element) async -> Void
) async {
// A task group automatically waits for all of its
// sub-tasks to complete, while also performing those
// tasks in parallel:
await withTaskGroup(of: Void.self) { group in
for element in self {
group.addTask {
await operation(element)
}
}
}
}
}
Now I have some protocol
protocol ProtocolConformingActors: Actor {
func bar() async throws
}
This leads me to running my function
func foo() async throws {
let actorsAndOrders: [Int: ProtocolConformingActors] = [1:actor1, 2:actor2, 3:actor3]
// Get order
var orders: [Int] = []
for entry in actorsAndOrders {
orders.append(entry.key)
}
orders.sort()
// Run func
await orders.asyncForEach { order in
let actor = actorsAndOrders[order]
try await actor?.bar()
}
}
And this is where the problem occurs. Like I mentioned above, these calls need to be async because bar()
is modifying isolated properties on each actor. Because in order to make this happen, I need to use the asyncForEach, but as I understand it, the asyncForEach
loop sets up and runs each function bar()
in parallel. But they need to be run in order.
Is there a way I can make each thread wait until a condition is met?
I was thinking I might be able to use the condition orders[0] == order
and when bar()
is done running, remove the first entry from the orders
array, which could make it tell the next thread it can wake up again.
But while the apple documentation seems to indicate that there is a wait(until:)
function on NSCondition
, I can't seem to make it work.