Make the actor identity type an associated type of ActorTransport

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.
This commit is contained in:
Doug Gregor
2021-11-03 08:58:21 -07:00
parent f83775bfc5
commit 4aacc1c99e
8 changed files with 92 additions and 29 deletions

View File

@@ -39,6 +39,9 @@ public protocol DistributedActor:
/// The type of transport used to communicate with actors of this type.
associatedtype Transport: ActorTransport
/// The type of identity used by the transport.
typealias Identity = Transport.Identity
/// Resolves the passed in `identity` against the `transport`, returning
/// either a local or remote actor reference.
///
@@ -51,11 +54,7 @@ public protocol DistributedActor:
///
/// - Parameter identity: identity uniquely identifying a, potentially remote, actor in the system
/// - Parameter transport: `transport` which should be used to resolve the `identity`, and be associated with the returned actor
// FIXME: Partially blocked on SE-309, because then we can store ActorIdentity directly
// We want to move to accepting a generic or existential identity here
// static func resolve<Identity>(_ identity: Identity, using transport: ActorTransport)
// throws -> Self where Identity: ActorIdentity
static func resolve(_ identity: AnyActorIdentity, using transport: Transport)
static func resolve(_ identity: Identity, using transport: Transport)
throws -> Self
/// The `ActorTransport` associated with this actor.
@@ -77,7 +76,7 @@ public protocol DistributedActor:
///
/// Conformance to this requirement is synthesized automatically for any
/// `distributed actor` declaration.
nonisolated var id: AnyActorIdentity { get }
nonisolated var id: Identity { get }
}
// ==== Hashable conformance ---------------------------------------------------
@@ -109,7 +108,7 @@ extension DistributedActor {
"in Decoder.userInfo, while decoding \(Self.self).")
}
let id: AnyActorIdentity = try transport.decodeIdentity(from: decoder)
let id: Identity = try transport.decodeIdentity(from: decoder)
self = try Self.resolve(id, using: transport)
}
@@ -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
@usableFromInline let _hashInto: (inout Hasher) -> ()
@usableFromInline let _equalTo: (Any) -> Bool
@@ -186,7 +186,7 @@ public struct AnyActorIdentity: ActorIdentity, @unchecked Sendable, CustomString
"ActorTransport not available under the decoder.userInfo")
}
self = try transport.decodeIdentity(from: decoder)
self = try transport.decodeAnyIdentity(from: decoder)
}
public func encode(to encoder: Encoder) throws {