Section 17/201 menit

17. Improved async let Cancellation Semantics

17. Improved async let Cancellation Semantics

Teori: Masalah Cancellation di Swift 6.0

Di Swift 6.0, ketika async let binding keluar scope, child tasks mungkin tidak segera di-cancel dalam semua skenario. Ini bisa menyebabkan:

  • Pekerjaan yang tidak diperlukan terus berjalan
  • Resource yang tidak di-release tepat waktu
  • Perilaku yang sulit diprediksi

Swift 6.2 memperketat semantik ini:

swift
// Swift 6.2: cancellation lebih deterministic dan immediate

func loadWithFallback() async throws -> Data {
    async let primary = fetchFromPrimaryServer()    // mulai
    async let backup = fetchFromBackupServer()      // mulai concurrent

    do {
        let data = try await primary  // tunggu primary
        // Swift 6.2: 'backup' task SEGERA di-cancel saat primary berhasil
        // Swift 6.0: 'backup' mungkin masih berjalan sebentar
        return data
    } catch {
        // Primary gagal — gunakan backup (sudah berjalan concurrent)
        return try await backup
    }
    // Setelah scope selesai: semua async let yang belum di-await otomatis di-cancel
}

Cancellation Propagation yang Lebih Baik

swift
// Pattern: race between multiple sources, cancel loser
func fetchWithRace(timeout: Duration) async throws -> Data {
    async let result = fetchData()
    async let timeoutSignal: Void = Task.sleep(for: timeout)

    // Whichever finishes first wins
    do {
        return try await result  // kalau ini selesai duluan...
        // 'timeoutSignal' task di-cancel segera di Swift 6.2
    } catch {
        // Timeout terjadi — result task di-cancel
        throw FetchError.timeout
    }
}

Kapan Ini Penting

Ini penting ketika:

  • Kamu menggunakan async let untuk "racing" beberapa operasi
  • Resource yang digunakan oleh async let mahal (network connections, file handles)
  • Perlu behavior yang predictable dan deterministik