Sobes.tech
Middle

Ar šiameje reikia naudoti asinchroninį vykdytoją?

sobes.tech AI

Atsakymas iš AI

Taip, tai būtina.

Kai prieinama actor iš išorinio izoliuoto konteksto (šiuo atveju iš globalinio konteksto), kompiliatorius garantuoja srauto saugumą, reikalaujant asinchroninio prieigos.

// Demonstracinis protokolas
protocol DataFetcher {
    func fetchData() async -> String
}

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

    func updateCache(key: String, value: String) {
        cache[key] = value // Veikia `actor` izoliuotame kontekste
    }

    func cachedData(forKey key: String) -> String? {
        return cache[key] // Veikia `actor` izoliuotame kontekste
    }

    nonisolated func clearCacheIsolated() {
        // Ši funkcija pažymėta kaip nonisolated ir neturi prieigos prie `actor` būsenos
        // Prieiga reikalauja asinchroninio iškvietimo
    }
}


class DataLoader {
    let cache: DataCache // Nuoroda į `actor`

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

    func loadData(key: String) async -> String {
        // Asinchroninis prieigos prie `actor`
        if let cached = await cache.cachedData(forKey: key) {
            return cached
        }

        // ... duomenų įkėlimo logika ...
        let newData = "Data for \(key)"

        // Asinchroninis `actor` atnaujinimas
        await cache.updateCache(key: key, value: newData)

        return newData
    }

    func attemptClearCacheAsync() async {
        // Asinchroninis `actor` metodo iškvietimas iš išorės
        await cache.clearCacheIsolated()
    }

    func attemptClearCacheDirect() {
        // Kompiliatoriaus klaida:
        // `actor` izoliuoto `clearCacheIsolated()` metodo
        // negalima iškviesti iš ne-izoliuoto konteksto
        // cache.clearCacheIsolated()
    }
}

Šiame pavyzdyje:

  • updateCache ir cachedData metodai vykdomi DataCache izoliuotame kontekste ir prieinami sinchroniškai actor viduje.
  • cache.cachedData(forKey: key) ir cache.updateCache(key: key, value: newData) iškvietimai iš loadData metodo (kuris yra už actor konteksto) reikalauja await žodžio, kuris žymi asinchroninį vykdymą ir asinchroninio vykdytojo naudojimą. actor vykdytojas atsakingas už šių operacijų vykdymą tvarka, užtikrinant išskirtinį prieigą prie actor būsenos.
  • clearCacheIsolated metodas pažymėtas kaip nonisolated, tačiau jam taip pat galimas asinchroninis iškvietimas await cache.clearCacheIsolated() iš išorės actor, nors tai nėra būtina šiuo atveju (kadangi šis metodas nekeičia actor būsenos).
  • Tiesioginis sinchroninis iškvietimas cache.clearCacheIsolated() iš ne-izoliuoto konteksto (kaip attemptClearCacheDirect) sukelia kompiliatoriaus klaidą, patvirtindamas asinchroninio prieigos poreikį.

Taigi, saugiai sąveikaujant su actor iš jo konteksto, būtina naudoti asinchroninius iškvietimus, kurie vykdomi naudojant asinchroninį vykdytoją, valdomą pačio actor.