Sobes.tech
Middle

Оё дар ин ҳолат зарур аст, ки як иҷрокунандаи асинхронӣ истифода шавад?

sobes.tech AI

Ҷавоб аз AI

დიახ, ეს აუცილებელია.

როდესაც გარე კონტექსტიდან (ამ შემთხვევაში გლობალური კონტექსტიდან) მიმართავთ actor-ს იზოლირებულ კონტექსტში, კომპილატორი გარანტირებს ნაკადების უსაფრთხოებას, მოთხოვნით ასინქრონული წვდომა.

// დემონსტრაციული პროტოკოლი
protocol DataFetcher {
    func fetchData() async -> String
}

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

    func updateCache(key: String, value: String) {
        cache[key] = value // ასრულებს `actor`-ის იზოლირებულ კონტექსტში
    }

    func cachedData(forKey key: String) -> String? {
        return cache[key] // ასრულებს `actor`-ის იზოლირებულ კონტექსტში
    }

    nonisolated func clearCacheIsolated() {
        // ეს ფუნქცია აღნიშნულია როგორც nonisolated და არ აქვს წვდომა `actor`-ის მდგომარეობაზე
        // მის მისაღწევად საჭიროა ასინქრონული გამოძახება
    }
}


class DataLoader {
    let cache: DataCache // `actor`-ის მიმთითებელი

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

    func loadData(key: String) async -> String {
        // ასინქრონული წვდომა `actor`-თან
        if let cached = await cache.cachedData(forKey: key) {
            return cached
        }

        // ... მონაცემების ჩატვირთვის ლოგიკა ...
        let newData = "Data for \(key)"

        // ასინქრონული განახლება `actor`-ში
        await cache.updateCache(key: key, value: newData)

        return newData
    }

    func attemptClearCacheAsync() async {
        // ასინქრონული გამოძახება `actor`-ის მეთოდზე გარედან
        await cache.clearCacheIsolated()
    }

    func attemptClearCacheDirect() {
        // კომპილატორის შეცდომა:
        // `clearCacheIsolated()`-ის `actor`-ის იზოლირებული ინსტანცია ვერ გამოიძახება არა-იზოლირებულ კონტექსტიდან
        // cache.clearCacheIsolated()
    }
}

ამ მაგალითში:

  • მეთოდები updateCache და cachedData შესრულდება DataCache-ის იზოლირებულ კონტექსტში და ხელმისაწვდომია სინქრონულად actor-ის შიგნით.
  • გამოძახებები 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.