Sobes.tech
Middle

Szükséges-e ebben az esetben aszinkron végrehajtót használni?

sobes.tech MI

Válasz az MI-től

Igen, szükséges.

Amikor az actor-hoz külsőleg hozzáférünk egy elszigetelt kontextusból (jelen esetben a globális kontextusból), a fordító garantálja a szálbiztosságot, és aszinkron végrehajtást ír elő.

// Demonstrációs protokoll
protocol DataFetcher {
    func fetchData() async -> String
}

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

    func updateCache(key: String, value: String) {
        cache[key] = value // Az actor elszigetelt kontextusában fut
    }

    func cachedData(forKey key: String) -> String? {
        return cache[key] // Az actor elszigetelt kontextusában fut
    }

    nonisolated func clearCacheIsolated() {
        // Ez a függvény nonisolated-ként van megjelölve, és nem fér hozzá az actor állapotához
        // Hozzáféréshez aszinkron hívás szükséges
    }
}


class DataLoader {
    let cache: DataCache // Az actor hivatkozás

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

    func loadData(key: String) async -> String {
        // Aszinkron hozzáférés az actor-hoz
        if let cached = await cache.cachedData(forKey: key) {
            return cached
        }

        // ... adatok betöltési logika ...
        let newData = "Data for \(key)"

        // Aszinkron frissítés az actor-ban
        await cache.updateCache(key: key, value: newData)

        return newData
    }

    func attemptClearCacheAsync() async {
        // Aszinkron hívás az actor metódusára külsőleg
        await cache.clearCacheIsolated()
    }

    func attemptClearCacheDirect() {
        // Fordítási hiba:
        // Actor-szigetelt példánymetódus 'clearCacheIsolated()' nem hívható meg nem-szigetelt kontextusból
        // cache.clearCacheIsolated()
    }
}

Ebben a példában:

  • A updateCache és cachedData metódusok az DataCache elszigetelt kontextusában futnak, és szinkron módon elérhetők az actor-n belül.
  • A cache.cachedData(forKey: key) és cache.updateCache(key: key, value: newData) hívások a loadData metódusból (amely kívül van az actor-on) await kulcsszót igényelnek, ami aszinkron végrehajtást és az aszinkron végrehajtó használatát jelenti. Az actor végrehajtó felelős ezeknek a műveleteknek a végrehajtásáért az exkluzív hozzáférés garantálásával.
  • A clearCacheIsolated metódus nonisolated-ként van megjelölve, de mégis az aszinkron hívás await cache.clearCacheIsolated() érvényes kívülről az actor-on, bár ez nem kötelező a szálbiztonság garantálásához ebben az esetben (mivel a metódus nem módosítja az actor állapotát).
  • A közvetlen szinkron hívás cache.clearCacheIsolated()-re nem elszigetelt kontextusból (például az attemptClearCacheDirect-ben) fordítási hibát eredményez, megerősítve az aszinkron hozzáférés szükségességét.

Így, az actorrel való biztonságos interakcióhoz kívülről kell aszinkron hívásokat használni, amelyek az actor által irányított aszinkron végrehajtó segítségével történnek.