Sobes.tech
Middle

Da li je potrebno koristiti asinhroni izvršilac u ovom slučaju?

sobes.tech АИ

Одговор од АИ

Да, потребно је.

Када приступате actor изван изолованог контекста (у овом случају из глобалног контекста), компајлер гарантује безбедност у раду са нитима, захтевајући асинхронај приступ.

// Демонстрациони протокол
protocol DataFetcher {
    func fetchData() async -> String
}

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

    func updateCache(key: String, value: String) {
        cache[key] = value // Извршава се у изолованом контексту акторa
    }

    func cachedData(forKey key: String) -> String? {
        return cache[key] // Извршава се у изолованом контексту акторa
    }

    nonisolated func clearCacheIsolated() {
        // Ова функција је означена као nonisolated и нема приступ стању акторa
        // За приступ је потребан асинхронај позив
    }
}


class DataLoader {
    let cache: DataCache // Референца на актор

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

    func loadData(key: String) async -> String {
        // Асинхронај приступ актору
        if let cached = await cache.cachedData(forKey: key) {
            return cached
        }

        // ... логика учитавања података ...
        let newData = "Data for \(key)"

        // Асинхрона ажурирање акторa
        await cache.updateCache(key: key, value: newData)

        return newData
    }

    func attemptClearCacheAsync() async {
        // Асинхронај позив метода акторa изван
        await cache.clearCacheIsolated()
    }

    func attemptClearCacheDirect() {
        // Грешка компајлера:
        // Метода `clearCacheIsolated()` актор-изолиране инстанце не може бити позвана из не-изолираног контекста
        // cache.clearCacheIsolated()
    }
}

У овом примеру:

  • Методи updateCache и cachedData извршавају се у изолованом контексту DataCache и доступни су синхроно унутар актор.
  • Позиви cache.cachedData(forKey: key) и cache.updateCache(key: key, value: newData) из метода loadData (који је ван actor контекста) захтевају кључну реч await, што означава асинхроно извршавање и коришћење асинхроног извршитеља. Извршитељ actor одговоран је за извршавање ових операција у реду, гарантујући ексклузиван приступ стању actor.
  • Метод clearCacheIsolated је означен као nonisolated, али је и на њега могуће позвати асинхронај await cache.clearCacheIsolated() изван actor-а, иако то није обавезно за гаранцију безбедности у овом случају (јер овај метод не мења стање actor).
  • Примарни синхрони позив cache.clearCacheIsolated() из не-изолираног контекста (као у attemptClearCacheDirect) доводи до грешке компајлера, што потврђује потребу за асинхроним приступом.

Стога, за безбедну интеракцију са actor изван његовог контекста је потребно користити асинхроне позиве који се извршавају помоћу асинхроног извршитеља којим управља сам actor.