Sobes.tech
Middle

Je potrebné použiť asynchrónneho vykonávateľa v tomto prípade?

sobes.tech AI

Odpoveď od AI

Áno, je to potrebné.

Pri prístupe k actor zvonku z izolovaného kontextu (v tomto prípade z globálneho kontextu) zaručuje prekladač bezpečnosť vlákien, vyžadujúc asynchrónny prístup.

// Demonstratívny protokol
protocol DataFetcher {
    func fetchData() async -> String
}

actor DataCache {
    var cache: [String: String] = [:]

    func updateCache(key: String, value: String) {
        cache[key] = value // Beží v izolovanom kontexte aktora
    }

    func cachedData(forKey key: String) -> String? {
        return cache[key] // Beží v izolovanom kontexte aktora
    }

    nonisolated func clearCacheIsolated() {
        // Táto funkcia je označená ako nonisolated a nemá prístup k stavu aktora
        // Na prístup je potrebný asynchrónny volanie
    }
}


class DataLoader {
    let cache: DataCache // Odkaz na aktor

    init(cache: DataCache) {
        self.cache = cache
    }

    func loadData(key: String) async -> String {
        // Asynchrónny prístup k aktoru
        if let cached = await cache.cachedData(forKey: key) {
            return cached
        }

        // ... logika načítania dát ...
        let newData = "Data for \(key)"

        // Asynchrónne aktualizovanie aktora
        await cache.updateCache(key: key, value: newData)

        return newData
    }

    func attemptClearCacheAsync() async {
        // Asynchrónne volanie metódy aktora zvonku
        await cache.clearCacheIsolated()
    }

    func attemptClearCacheDirect() {
        // Chyba kompilátora:
        // Metóda inštancie izolovaná od aktora 'clearCacheIsolated()' nemôže byť
        // volaná z ne-izolovaného kontextu
        // cache.clearCacheIsolated()
    }
}

V tomto príklade:

  • Metódy updateCache a cachedData sa vykonávajú v izolovanom kontexte DataCache a sú dostupné synchronne vo vnútri aktora.
  • Volania cache.cachedData(forKey: key) a cache.updateCache(key: key, value: newData) z metódy loadData (ktorá je mimo kontextu actor) vyžadujú kľúčové slovo await, čo označuje asynchrónne vykonanie a použitie asynchrónneho vykonávateľa. Vykonávateľ actor je zodpovedný za vykonanie týchto operácií v poradí, zabezpečujúc exkluzívny prístup k stavu actor.
  • Metóda clearCacheIsolated je označená ako nonisolated, ale aj na ňu je platné asynchrónne volanie await cache.clearCacheIsolated() zvonku na actor, hoci to nie je povinné pre zabezpečenie vlákna-bezpečnosti v tomto prípade (pretože táto metóda nemení stav actor).
  • Priamy synchronný volanie cache.clearCacheIsolated() z ne-izolovaného kontextu (ako v attemptClearCacheDirect) spôsobí chybu kompilátora, čím potvrdzuje potrebu asynchrónneho prístupu.

Teda, pre bezpečnú interakciu s actor zvonku jeho kontextu je potrebné používať asynchrónne volania, ktoré sa vykonávajú pomocou asynchrónneho vykonávateľa riadeného samotným actor.