This is very very cool, congratulations! 
I skimmed just a bit of the project quickly, and had some questions that might help us inform and improve the distributed language feature.
Assigning IDs
I believe you need to do the
system.makeLocalActor(id: .greeter) {
Greeter(actorSystem: system)
}
dance because you want to provide a "well known" ID that clients can get. This is a common pattern and need and I've been thinking how we can help actor system authors out here.
We'd basically need a way to "pass in" extra metadata into the actor creation, such that assignID
can use an passed in ID, rather than be forced to generate one. Did I spot that right and do you think such capability would help so we could avoid having these tricks with closures?
Resolving protocols
I suspect your use cases are such that you'd like to have a server expose a distributed actor to "clients".
The current design is really tailored to symmetric nodes, so all nodes have the same code -- such as a cluster.
I'm very interested in lifting this limitation, such that we could avoid the awkward dance as Documentation needs to point out.
Ideally, we'd be able to (API not final, still working on a draft):
public protocol WeatherStationRegistry: DistributedActor
where ActorSystem == WebSocketActorSystem {
distributed func getStationsNear(
latitude: Double,
longitude: Double,
radius: Double) -> [WeatherStation]
}
and then be able to ((any WeatherStationRegistry).resolve(...)
on the client, without knowing the exact implementation.
You'd be able to put "the API" into a shared module, that clent and server depend on -- but only server actually has an implementation for
System IDs
I think that's an okey approach, with the client not having to care about identity.
Though I do wonder if it wouldn't be nicer to have the ActorSystem initializer itself to start in a specific "mode" rather than having to runServer later on 
Did you have some thoughts on that and decided to go with the method after all?
It seems like we would NOT want to have a client side server runServer
if it has a random ID after all -- or did you have use cases for it?
I was surprised though that the ActorIdentity
uses NodeIdentity
which is only a string -- rather than have the Node identity be (protocol, host, port)
. Have you considered using a triple like that for node identity -- this way a single client system can manage connections to multiple servers if it needed to do so.
Generally it is preferred to have "one actor system that manages connections" style wise, rather than "many actor systems, PER connection". That's how cluster and some other implementations work and I'd recommend trying that approach 
Very cool overall, and I hope we can improve the language feature as well as library and get some great use out of it!
As a fun side project you could even consider supporting swift-distributed-tracing in it! 