-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Eliminate required type erasure from distributed actors #40033
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eliminate required type erasure from distributed actors #40033
Conversation
…rotocol. Eliminate the required use of existentials in distributed actors by introducing the `Transport` associated type into the `DistributedActor` protocol. Each distributed actor has a known (concrete) actor transport type, reducing storage requirements and transport dynamism when it isn't needed. Distributed actors can manually specify their `Transport` associated type or pick up a default by looking for a type named `DefaultActorTransport`. A library that vends an actor transport can make create a public typealias `DefaultActorTransport` referring to its transport, so importing that library and defining a distributed actor will use that library's transport. Introduce a type-erased `AnyActorTransport` type to provide an explicitly dynamic actor transport. This is still an important option, e.g., for cases where one wants to be able to dynamically change the transport for testing or different kinds of deployment. For now, we default to this transport in the library (via `DefaultActorTransport`), but we may very well want to eliminate this because it will be ambiguous with client libraries that vend their own `DefaultActorTransport`.
Eliminate the use of the type-erased `AnyActorIdentity` within the distributed actor protocol by exposing the identity type of an actor transport as an associated type, `Identity`, which is then used to refer to all actors that have that transport. Retain `AnyActorIdentity`, because it remains useful for type-erasing actor transports, especially as the `Identity` type for `AnyActorTransport`. For now, make it the default type of `Identity`: this helps smooth over the transition from use of `AnyActorIdentity`, but we might want to remove this to make use of the type-erased forms always opt-in.
@swift-ci please test |
@swift-ci please built toolchain |
@swift-ci please build toolchain |
Linux Toolchain (Ubuntu 16.04) Install command |
@@ -151,6 +150,7 @@ public protocol ActorIdentity: Sendable, Hashable, Codable {} | |||
|
|||
@available(SwiftStdlib 5.6, *) | |||
public struct AnyActorIdentity: ActorIdentity, @unchecked Sendable, CustomStringConvertible { | |||
// FIXME: This probably shouldn't be public | |||
public let underlying: Any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
weirdly enough, it has to be public or we have to expose it some other way, perhaps some func as(_ type: T) -> T?
? The reason is that when we get "some distributed actor" we need to check if we understand the identity quite often (in the cluster I hit this a lot).
Second thought: If we adopted the well-typed Identity
i guess this would become unnecessary since we would only work with "our" actors hm... I do keep wondering if it isn't too limiting to erase without being able to pull out the underlying identity though hm...
Summary: Not sure yet 🤔
macOS Toolchain Install command |
I'm going to go ahead with this as a baby step and then we can tweak it further |
Eliminate the required use of existentials in distributed actors by introducing the
Transport
associated type into theDistributedActor
protocol and theIdentity
associated type into theActorTransport
protocol. This way, each distributed actor has a known (concrete) actor transport type and actor identity type, reducing storage requirements to the minimum and eliminating dynamic dispatch when it isn't needed.Distributed actors can manually specify their
Transport
associated type or pick up a default by looking for a type namedDefaultActorTransport
. A library that vends an actor transport can make create a public typealiasDefaultActorTransport
referring to its transport, so importing that library and defining a distributed actor will use that library's transport.Introduce a type-erased
AnyActorTransport
type to provide an explicitly dynamic actor transport. This is still an important option, e.g., for cases where one wants to be able to dynamically change the transport for testing or different kinds of deployment.Introduce some potentially-temporary defaults for both the transport and identity, to smooth the transition to this newer formulation. Add a public typ ealias
DefaultActorTransport
that refers toAnyActorTransport
, so that clients will get the same "type-erased by default" behavior they have today (although we'll still end up breaking source code here). Additionally, default theIdentity
associated type toAnyActorIdentity
, which matches today's default. We likely want to eliminate these defaults, because theDefaultActorTransport
definition will likely cause ambiguities with client libraries and, philosophically, the performance costs of type erasure should always be opt-in.