Sobes.tech
Middle

Faut-il utiliser un exécuteur asynchrone dans ce cas?

sobes.tech IA

Réponse de l'IA

Oui, c'est nécessaire.

Lors de l'accès à actor depuis l'extérieur de son contexte isolé (dans ce cas, depuis le contexte global), le compilateur garantit la sécurité des threads, en exigeant que l'accès soit effectué de manière asynchrone.

// Protocole pour démonstration
protocol DataFetcher {
    func fetchData() async -> String
}

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

    func updateCache(key: String, value: String) {
        cache[key] = value // Exécuté dans le contexte isolé de l'acteur
    }

    func cachedData(forKey key: String) -> String? {
        return cache[key] // Exécuté dans le contexte isolé de l'acteur
    }

    nonisolated func clearCacheIsolated() {
        // Cette fonction est marquée comme non isolée et n'a pas accès à l'état de l'acteur
        // Pour y accéder, une appel asynchrone est requis
    }
}


class DataLoader {
    let cache: DataCache // Référence à l'acteur

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

    func loadData(key: String) async -> String {
        // Accès asynchrone à l'acteur depuis l'extérieur
        if let cached = await cache.cachedData(forKey: key) {
            return cached
        }

        // ... logique de chargement des données ...
        let newData = "Data for \(key)"

        // Mise à jour asynchrone de l'acteur
        await cache.updateCache(key: key, value: newData)

        return newData
    }

    func attemptClearCacheAsync() async {
        // Appel asynchrone à la méthode de l'acteur depuis l'extérieur
        await cache.clearCacheIsolated()
    }

    func attemptClearCacheDirect() {
        // Erreur de compilation :
        // La méthode d'instance isolée par l'acteur 'clearCacheIsolated()' ne peut pas être
        // appelée depuis un contexte non isolé
        // cache.clearCacheIsolated()
    }
}

Dans cet exemple :

  • Les méthodes updateCache et cachedData s'exécutent dans le contexte isolé de DataCache et sont accessibles de manière synchrone à l'intérieur de l'acteur.
  • Accéder à cache.cachedData(forKey: key) et cache.updateCache(key: key, value: newData) depuis la méthode loadData (qui est en dehors du contexte de l'acteur) nécessite le mot-clé await, ce qui indique une exécution asynchrone et l'utilisation d'un exécuteur asynchrone. L'exécuteur de l'acteur est responsable de l'exécution de ces opérations dans l'ordre, garantissant un accès exclusif à l'état de l'acteur.
  • La méthode clearCacheIsolated est marquée comme nonisolated, mais même son appel asynchrone await cache.clearCacheIsolated() est valide depuis l'extérieur de l'acteur, bien que cela ne soit pas obligatoire pour garantir la sécurité des threads dans ce cas (car la méthode ne modifie pas l'état de l'acteur).
  • L'appel synchrone direct cache.clearCacheIsolated() depuis un contexte non isolé (comme dans attemptClearCacheDirect) entraîne une erreur de compilation, confirmant la nécessité d'un accès asynchrone.

Ainsi, pour interagir en toute sécurité avec un acteur depuis son contexte externe, il est nécessaire d'utiliser des appels asynchrones qui s'exécutent à l'aide d'un exécuteur asynchrone géré par l'acteur lui-même.