Section 12/172 menit

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 await point, 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.

swift
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.