Swift ConcurrencyのSendableとIsolation Domain / Isolation Boundaryがどのように機能してデータ競合を防ぐのか
学習のポイント
- Isolation
- Isolation boundary
- Sendable
These domains will always fall into one of three categories:
- Non-isolated
- Isolated to an actor value
- Isolated to a global actor
Task のインスタンスごとに Isolation が存在する
ただし、下記のような場合は MainActor の Isolation に所属する
Task { @MainActor
Data isolation is the mechanism used to protect shared mutable state. But it is often useful to talk about an independent unit of isolation. This is known as an isolation domain.
データの隔離は、共有される可変の状態を保護するためのメカニズムです。しかし、独立した隔離単位について話すことが有用な場合が多く、これを隔離ドメインと呼びます。
In some cases, all values of a particular type are safe to pass across isolation boundaries because thread-safety is a property of the type itself. This is represented by the Sendable protocol.
特定の型のすべての値が、スレッドセーフであることから隔離の境界を越えて渡しても安全である場合があります。これは、型自体が持つスレッドセーフの特性に基づいており、Sendableプロトコルで表されます。
Task の Isolation Domain で実行するので、 Task はそれぞれの Isolation boundary を跨ぐので、 Sendable への準拠が必要
Sendable に準拠していない値は capture できない
呼び出し元が MainActor で呼ばれたメソッドが Non-isolated であれば Isolation boundary を跨ぐのでコンパイルエラーになる
この挙動は紛らわしいので、呼び出し元の Isolation Dmain を継承するプロポーザルが出ている
Global Actor でないとキャプチャしていないと Context が継承されない問題の改善
Isolation Domain がそれぞれ存在していて、その境界が Isolation boundary でそれを超えることができるのは Sendable
越えられないものをコンパイルで検知可能になったのが Swift 6
特定の Isolation Domain でしか利用されないことが静的に判断できればコンパイルを通すのが Region Based Isolation
Sendable ではなくても Isolation boundary を超えることができる
プロポーザルは長いけど、使う側からするとその全てを理解していなくても大丈夫
sending
Suspension Point
Actor が内部で Queue を管理して処理してくれている
優先順位付きの管理
実際に手を動かしてコンパイラの理解を深めるのが大事