Resurrecting this thread. Is there a possibility of this actually being handled in the language? Or is this something we just have to accept?
Personally, apart from in the most trivial of cases, I no longer reach for actors as a synchronisation mechanism precisely due to the uncertainty of Task ordering in cases where it seems like we should be able to guarantee it.
The latest case was similar to OP in that I have a Combine publisher that receives events from a UI at a very high frequency. The type that owns the publisher is an actor so I need to create a Task to handle the published value. I have test cases which will invariably fail around ~20% of the time if I run them 100 times due to the events being published in the expected order, but the Task creation throwing things out of whack. This is even the case if the publisher recieves events on the main thread and the tasks are created on the main actor using the highest priority.
Here's the offending code:
timePublisher
.removeDuplicates()
.receive(on: DispatchQueue.main)
.sink { [weak self] time in
Task { @MainActor [weak self] in
await self?.handleTimeUpdate(to: time)
}
}
.store(in: &subscriptions)
}
I can see from logging that the publisher receives the events in the correct order, but the code inside the Task will not always start in the correct order.
I'm not sure what the correct solution is using Swift Concurrency so I reverted to using a combination of locks and dispatch queues across this entire feature