Middle
Je v tomto případě nutné použít asynchronního exekutora?
sobes.tech AI
Odpověď od AI
Ano, je to nutné.
Při přístupu k actor z vnějšího izolovaného kontextu (v tomto případě z globálního kontextu) zaručuje překladač vlákna-bezpečnost tím, že vyžaduje asynchronní přístup.
// Demonstrativní protokol
protocol DataFetcher {
func fetchData() async -> String
}
actor DataCache {
var cache: [String: String] = [:]
func updateCache(key: String, value: String) {
cache[key] = value // Běží v izolovaném kontextu aktoru
}
func cachedData(forKey key: String) -> String? {
return cache[key] // Běží v izolovaném kontextu aktoru
}
nonisolated func clearCacheIsolated() {
// Tato funkce je označena jako nonisolated a nemá přístup ke stavu aktoru
// Přístup vyžaduje asynchronní volání
}
}
class DataLoader {
let cache: DataCache // Odkaz na aktor
init(cache: DataCache) {
self.cache = cache
}
func loadData(key: String) async -> String {
// Asynchronní přístup k aktoru
if let cached = await cache.cachedData(forKey: key) {
return cached
}
// ... logika načítání dat ...
let newData = "Data for \(key)"
// Asynchronní aktualizace aktoru
await cache.updateCache(key: key, value: newData)
return newData
}
func attemptClearCacheAsync() async {
// Asynchronní volání metody aktoru zvenčí
await cache.clearCacheIsolated()
}
func attemptClearCacheDirect() {
// Chyba kompilace:
// Metoda instance izolovaná od aktoru 'clearCacheIsolated()' nemůže být volána z ne-izolovaného kontextu
// cache.clearCacheIsolated()
}
}
V tomto příkladu:
- Metody
updateCacheacachedDatajsou prováděny v izolovaném kontextuDataCachea jsou dostupné synchronně uvnitř aktoru. - Volání
cache.cachedData(forKey: key)acache.updateCache(key: key, value: newData)z metodyloadData(která je mimo kontextactor) vyžaduje klíčové slovoawait, což označuje asynchronní provedení a použití asynchronního vykonavatele. Vykonavatelactorje zodpovědný za provádění těchto operací v pořadí, zajišťujíc exkluzivní přístup ke stavuactor. - Metoda
clearCacheIsolatedje označena jakononisolated, ale i na ni je platné asynchronní voláníawait cache.clearCacheIsolated()zvenčíactor, i když to není povinné pro zajištění vlákna-bezpečnosti v tomto případě (protože metoda nemění stav aktoru). - Přímé synchronní volání
cache.clearCacheIsolated()z ne-izolovaného kontextu (například vattemptClearCacheDirect) způsobí kompilátorovou chybu, což potvrzuje nutnost asynchronního přístupu.
Tedy, pro bezpečnou interakci s aktorem zvenčí jeho kontextu je nutné používat asynchronní volání, která jsou prováděna pomocí asynchronního vykonavatele řízeného samotným aktorem.