Skip to content

Instantly share code, notes, and snippets.

@yannxou
Last active September 15, 2023 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yannxou/b7ae90f1278500d0a63c27731e7cd1cf to your computer and use it in GitHub Desktop.
Save yannxou/b7ae90f1278500d0a63c27731e7cd1cf to your computer and use it in GitHub Desktop.
Swift: Handling actor reentrancy correctly
// Code from: https://alexdremov.me/swift-actors-common-problems-and-tips/
import Foundation
actor ActivitiesStorage {
var cache = [UUID: Task<Data?, Never>]()
func retrieveHeavyData(for id: UUID) async -> Data? {
if let task = cache[id] {
return await task.value
}
// ...
let task = Task {
await requestDataFromDatabase(for: id)
}
// Notice that it is set before `await`
// So, the following calls will have this task available
cache[id] = task
return await task.value // suspension
}
private func requestDataFromDatabase(for id: UUID) async -> Data? {
print("Performing heavy data loading!")
try! await Task.sleep(for: .seconds(1))
// ...
return nil
}
}
let id = UUID()
let storage = ActivitiesStorage()
Task {
let data = await storage.retrieveHeavyData(for: id)
}
Task {
let data = await storage.retrieveHeavyData(for: id)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment