Sobes.tech
Middle

Je v tomto případě nutné použít asynchronního exekutora?

sobes.tech AI

Odpověď od AI

Ano, je to nutné.

Při přístupu k actor z vnějšího izolovaného kontextu (v tomto případě z globálního kontextu) zaručuje překladač vlákna-bezpečnost tím, že vyžaduje asynchronní přístup.

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

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

    func updateCache(key: String, value: String) {
        cache[key] = value // Běží v izolovaném kontextu aktoru
    }

    func cachedData(forKey key: String) -> String? {
        return cache[key] // Běží v izolovaném kontextu aktoru
    }

    nonisolated func clearCacheIsolated() {
        // Tato funkce je označena jako nonisolated a nemá přístup ke stavu aktoru
        // Přístup vyžaduje asynchronní volání
    }
}


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

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

    func loadData(key: String) async -> String {
        // Asynchronní přístup k aktoru
        if let cached = await cache.cachedData(forKey: key) {
            return cached
        }

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

        // Asynchronní aktualizace aktoru
        await cache.updateCache(key: key, value: newData)

        return newData
    }

    func attemptClearCacheAsync() async {
        // Asynchronní volání metody aktoru zvenčí
        await cache.clearCacheIsolated()
    }

    func attemptClearCacheDirect() {
        // Chyba kompilace:
        // Metoda instance izolovaná od aktoru 'clearCacheIsolated()' nemůže být volána z ne-izolovaného kontextu
        // cache.clearCacheIsolated()
    }
}

V tomto příkladu:

  • Metody updateCache a cachedData jsou prováděny v izolovaném kontextu DataCache a jsou dostupné synchronně uvnitř aktoru.
  • Volání cache.cachedData(forKey: key) a cache.updateCache(key: key, value: newData) z metody loadData (která je mimo kontext actor) vyžaduje klíčové slovo await, což označuje asynchronní provedení a použití asynchronního vykonavatele. Vykonavatel actor je zodpovědný za provádění těchto operací v pořadí, zajišťujíc exkluzivní přístup ke stavu actor.
  • Metoda clearCacheIsolated je označena jako nonisolated, ale i na ni je platné asynchronní volání await cache.clearCacheIsolated() zvenčí actor, i když to není povinné pro zajištění vlákna-bezpečnosti v tomto případě (protože metoda nemění stav aktoru).
  • Přímé synchronní volání cache.clearCacheIsolated() z ne-izolovaného kontextu (například v attemptClearCacheDirect) způsobí kompilátorovou chybu, což potvrzuje nutnost asynchronního přístupu.

Tedy, pro bezpečnou interakci s aktorem zvenčí jeho kontextu je nutné používat asynchronní volání, která jsou prováděna pomocí asynchronního vykonavatele řízeného samotným aktorem.