Actor Reentrancy in macOS Apps - Preventing State Corruption

Fazm Team··2 min read

Actor Reentrancy in macOS Apps - Preventing State Corruption

Swift actors solve data races but they do not solve reentrancy. If you have worked with actors in a macOS app, you have probably hit this bug without realizing it.

The Reentrancy Problem

When an actor method hits an await point, the actor is free to run other methods. This means two calls to the same method can interleave. Your method reads a value, awaits a network call, then writes based on what it read - but another call changed the value during that await.

The result is state corruption that is nearly impossible to reproduce in testing. It only shows up under real concurrent load, and the symptoms look like random data inconsistencies.

Why Actors Alone Are Not Enough

Swift actors guarantee mutual exclusion at the synchronization boundary, but they do not guarantee that a method runs atomically from start to finish. Every await is a potential interleaving point. If your method has three await points, it can be interrupted three times.

This is by design - blocking the actor for the entire duration of a long async operation would kill performance. But it means you need a strategy for protecting multi-step operations.

The TaskGate Pattern

A TaskGate serializes access to critical sections within an actor. Instead of relying on the actor's built-in synchronization, you explicitly gate operations that must run without interleaving.

The pattern is simple: before entering a critical section, acquire the gate. If another operation holds it, wait. When you are done, release it. This gives you the atomicity that actors intentionally do not provide.

When You Need This

Not every actor method needs gating. The rule of thumb: if a method reads state, awaits something, then writes state based on what it read, it needs protection. If a method just reads or just writes without awaiting, the actor's built-in isolation is sufficient.

Common cases include: syncing local state with a remote API, processing queued items one at a time, and any read-modify-write cycle that spans an await.

Fazm is an open source macOS AI agent. Open source on GitHub.

More on This Topic

Related Posts