blog icon indicating copy to clipboard operation
blog copied to clipboard

How to deal with actor reentrancy in Swift

Open onmyway133 opened this issue 1 year ago • 0 comments

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

onmyway133 avatar May 05 '23 20:05 onmyway133