Concurrency: suspending an actor async func until the actor meets certain conditions

There's no existing pattern for this kind of "wait", other than the pseudo-wait via Task.sleep. I think the forthcoming Task.select might be helpful for this kind of thing, in the minimal case of suspending on a single outstanding task.

The only current solutions AFAIK are: use one of the with…Continuation functions at the deepest level of waiting, essentially bridging from the old completion-handler pattern back to Swift concurrency; or, use a custom AsyncStream to deliver completions of events you're waiting on.

You do face a second problem, though. Using await inside an actor is very bad news because actors are re-entrant. At the suspension point of such an await, other actor-isolated functions and accessors can run, so the awaiting function is not completely isolated as you might expect. This is fine if your actor has no breakable invariants that can be compromised across an internal suspension point, but that's very hard to ensure — and it pretty much takes away the isolation advantages that actors were intended to provide.

Proceed with extreme caution. :slight_smile:

3 Likes