12. Deadlock, Priority Inversion, dan Starvation
12. Deadlock, Priority Inversion, dan Starvation
Re-entrancy mencegah classic deadlock antar actor, tapi tiga masalah lain bisa muncul.
Priority Inversion
Task priority rendah memegang actor. Task priority tinggi await actor itu. Sementara task lain dengan priority menengah mengerjakan banyak hal lain di pool — task priority tinggi tertahan oleh task priority rendah.
Swift Concurrency punya priority escalation: saat task priority tinggi menunggu actor yang dipegang task priority rendah, runtime menaikkan priority task pemegang. Otomatis, tapi tidak gratis.
Mitigasi praktis:
- Hindari method actor yang sangat panjang (panjangkan = lebih sering jadi target inversion).
- Pecah work besar jadi banyak
awaitpoint, sehingga task lain bisa selip masuk.
Starvation: Actor Selalu Sibuk
Kalau actor terus-menerus menerima work dari banyak caller priority tinggi, work priority rendah bisa "tidak pernah dapat giliran". Executor actor adalah FIFO per priority level — tidak ada aging.
Mitigasi:
- Time-box operasi yang berpotensi panjang.
- Pisahkan high-priority dan low-priority work ke actor berbeda kalau memang ada bottleneck.
Self-Deadlock dengan Custom Executor
Kalau kamu pasang DispatchSerialQueue sebagai executor, lalu di dalam method actor kamu queue.sync { ... }, → deadlock, karena queue sedang menjalankan kamu.
actor X {
let queue = DispatchSerialQueue(label: "x")
nonisolated var unownedExecutor: UnownedSerialExecutor {
queue.asUnownedSerialExecutor()
}
func bad() {
queue.sync { } // ❌ deadlock
}
}
Cross-Actor "Deadlock" Saat Custom Executor
Jarang, tapi terjadi: dua actor dengan custom executor yang menunggu satu sama lain di operasi synchronous (bukan await). Default actor executor tidak punya masalah ini karena work-stealing.