SE-0336 and SE-0344 introduce the ability for actors to work in a distributed form – to read and write properties or call methods over a network using remote procedure calls (RPC).
This is every part as complicated a problem as you might imagine, but there are three things to make it easier:
await
calls we would no matter what, and if the actor happens to be local then the call is handled as a regular local actor function.distributed actor
then distributed func
as needed.So, we can write code like this to simulate someone tracking a trading card system:
// use Apple's ClusterSystem transport
typealias DefaultDistributedActorSystem = ClusterSystem
distributed actor CardCollector {
var deck: Set<String>
init(deck: Set<String>) {
self.deck = deck
}
distributed func send(card selected: String, to person: CardCollector) async -> Bool {
guard deck.contains(selected) else { return false }
do {
try await person.transfer(card: selected)
deck.remove(selected)
return true
} catch {
return false
}
}
distributed func transfer(card: String) {
deck.insert(card)
}
}
Because of the throwing nature of distributed actor calls, we can be sure it’s safe to remove the card from one collector if the call to person.transfer(card:)
didn’t throw.
Swift’s goal is that you can transfer your knowledge of actors over to distributed actors very easily, but there are some important differences that might catch you out.
First, all distributed functions must be called using try
as well as await
even if the function isn’t marked as throwing, because it’s possible for a failure to happen as a result of the network call going awry.
Second, all parameters and return values for distributed methods must conform to a serialization process of your choosing, such as Codable
. This gets checked at compile time, so Swift can guarantee it’s able to send and receive data from remote actors.
And third, you should consider adjusting your actor API to minimize data requests. For example, if you want to read the username
, firstName
, and lastName
properties of a distributed actor, you should prefer to request all three with a single method call rather than requesting them as individual properties to avoid potentially having to go back and forward over the network several times.
SPONSORED Debug 10x faster with Proxyman. Your ultimate tool to capture HTTPs requests/ responses, natively built for iPhone and macOS. You’d be surprised how much you can learn about any system by watching what it does over the network.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Download all Swift 5.7 changes as a playground Link to Swift 5.7 changes
Link copied to your pasteboard.