blog
blog copied to clipboard
How to deal with actor reentrancy in Swift
Perform check before and after suspension point
actor Worker {
var isDoing = false
var toBeDone = Set<String>()
func work(string: String) async {
if isDoing {
toBeDone.insert(string)
return
}
isDoing = true
await performHeavyWork(string: string)
isDoing = false
if let first = toBeDone.popFirst() {
await work(string: first)
}
}
private func performHeavyWork(string: String) async {
try? await Task.sleep(nanoseconds: 5_000_000_000)
print(string)
}
}
func main() {
let worker = Worker()
Array(0 ... 10).forEach { number in
Task.detached {
await worker.work(string: "\(number)")
}
}
}
main()
Read more
- https://stackoverflow.com/questions/70586562/how-to-prevent-actor-reentrancy-resulting-in-duplicative-requests