Sobes.tech
Middle

Moet er in dit geval een asynchrone executor worden gebruikt?

sobes.tech AI

Antwoord van AI

Ja, dat is nodig.

Bij toegang tot actor van buitenaf zijn zijn geïsoleerde context (in dit geval vanuit de globale context) garandeert de compiler threadveiligheid door te eisen dat de toegang asynchroon wordt uitgevoerd.

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

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

    func updateCache(key: String, value: String) {
        cache[key] = value // Wordt uitgevoerd binnen de geïsoleerde context van de actor
    }

    func cachedData(forKey key: String) -> String? {
        return cache[key] // Wordt uitgevoerd binnen de geïsoleerde context van de actor
    }

    nonisolated func clearCacheIsolated() {
        // Deze functie is gemarkeerd als nonisolated en heeft geen toegang tot de toestand van de actor
        // Toegang vereist een asynchrone aanroep
    }
}


class DataLoader {
    let cache: DataCache // Verwijzing naar de actor

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

    func loadData(key: String) async -> String {
        // Asynchrone toegang tot de actor van buitenaf
        if let cached = await cache.cachedData(forKey: key) {
            return cached
        }

        // ... logica voor het laden van gegevens ...
        let newData = "Data for \(key)"

        // Asynchrone update van de actor
        await cache.updateCache(key: key, value: newData)

        return newData
    }

    func attemptClearCacheAsync() async {
        // Asynchrone aanroep van de actor-methode van buitenaf
        await cache.clearCacheIsolated()
    }

    func attemptClearCacheDirect() {
        // Compileerfout:
        // Actor-geïsoleerde instantie-methode 'clearCacheIsolated()' kan niet worden
        // aangeroepen vanuit een niet-geïsoleerde context
        // cache.clearCacheIsolated()
    }
}

In dit voorbeeld:

  • De methoden updateCache en cachedData worden uitgevoerd binnen de geïsoleerde context van DataCache en zijn synoniem binnen de actor toegankelijk.
  • Toegang tot cache.cachedData(forKey: key) en cache.updateCache(key: key, value: newData) vanuit de methode loadData (die buiten de actor-context ligt) vereist het sleutelwoord await, wat wijst op asynchrone uitvoering en gebruik van een asynchrone executor. De executor van de actor is verantwoordelijk voor het uitvoeren van deze operaties in volgorde, wat exclusieve toegang tot de toestand van de actor garandeert.
  • De methode clearCacheIsolated is gemarkeerd als nonisolated, maar zelfs de asynchrone aanroep await cache.clearCacheIsolated() is geldig van buiten de actor, hoewel dit niet verplicht is om threadveiligheid te garanderen (omdat de methode de toestand van de actor niet wijzigt).
  • De directe synchrone aanroep cache.clearCacheIsolated() vanuit een niet-geïsoleerde context (zoals in attemptClearCacheDirect) leidt tot een compileerfout, wat de noodzaak van asynchrone toegang bevestigt.

Dus, om veilig te communiceren met een actor van buitenaf, is het noodzakelijk om asynchrone aanroepen te gebruiken die worden uitgevoerd met behulp van een door de actor beheerde asynchrone executor.