In WWDC 2021 video, Shield mutable state with Swift actors, they supply the next code snippet:
actor ImageDownloader {
non-public var cache: [URL: Image] = [:]
func picture(from url: URL) async throws -> Picture? {
if let cached = cache[url] {
return cached
}
let picture = strive await downloadImage(from: url)
cache[url] = cache[url, default: image]
return cache[url]
}
func downloadImage(from url: URL) async throws -> Picture { ... }
}
The difficulty is that actors supply reentrancy, so cache[url, default: image]
reference successfully ensures that even should you carried out a duplicative request due to some race, that you simply a minimum of examine the actor’s cache after the continuation, guaranteeing that you simply get the identical picture for the duplicative request.
And in that video, they say:
A greater answer can be to keep away from redundant downloads totally. We’ve put that answer within the code related to this video.
However there is no such thing as a code related to that video on the web site. So, what’s the higher answer?
I perceive the advantages of actor reentrancy (as mentioned in SE-0306). E.g., if downloading 4 photographs, one doesn’t wish to prohibit reentrancy, dropping concurrency of downloads. We might, successfully, like to attend for the results of a duplicative prior request for a selected picture if any, and if not, begin a brand new downloadImage
.