Notes

Swift concurrency

Actors do not remove the concurrency problem, they move it to the boundary where you can see it.

1 min read

The pitch for async/await is that it makes concurrent code read like sequential code. That is true and it is also the trap: it reads sequentially, so it is easy to stop noticing the suspension points, which are the only places anything interesting can go wrong.

Suspension points are the API

Every await is a place where the world can change underneath you. State you read before it may not hold after it.

func refresh() async {
    let stale = cache.snapshot()
    let fresh = try? await service.fetch()   // anything can happen here
    apply(fresh ?? stale)                     // is `stale` still current?
}

Actors fix the data race and not the logic race. Serialised access means two tasks will not corrupt the same field; it does not mean the second one is still doing something that makes sense.

Things worth being deliberate about

More once this is written properly.