From e73f180aa30816d837ac22bbf7b321ab7915aec4 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Wed, 20 Jul 2022 19:29:49 +0900 Subject: [PATCH] fix wellKnown name handling from props --- Sources/DistributedActors/ActorID.swift | 11 ++++++++++- Sources/DistributedActors/ActorMetadata.swift | 15 +++++++++++++-- .../OperationLogDistributedReceptionist.swift | 3 ++- Sources/DistributedActors/ClusterSystem.swift | 6 ++++-- Sources/DistributedActors/Props.swift | 7 +++++++ 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Sources/DistributedActors/ActorID.swift b/Sources/DistributedActors/ActorID.swift index b635d5b5e..ee70df1c8 100644 --- a/Sources/DistributedActors/ActorID.swift +++ b/Sources/DistributedActors/ActorID.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// import Distributed +import Foundation // ==== ---------------------------------------------------------------------------------------------------------------- // MARK: ActorID @@ -58,7 +59,7 @@ extension ClusterSystem.ActorID { let metadata = myself.id.metadata let key = myself[keyPath: storageKeyPath] if let value = metadata[key.id] { - fatalError("Attempted to override ActorID Metadata for key \(key.id):\(key.keyType) which already had value: \(value); with new value: \(String(describing: newValue))") + fatalError("Attempted to override ActorID Metadata for key \(key.id):\(key.keyType) which already had value: [\(value)] with new value: [\(String(describing: newValue))]") } metadata[key.id] = newValue @@ -140,6 +141,10 @@ extension ClusterSystem { case .remote(let node): return node } } + + #if DEBUG + private var debugID: UUID = UUID() + #endif /// Collection of tags associated with this actor identity. /// @@ -367,6 +372,10 @@ extension ActorID: CustomStringConvertible { if !self.metadata.isEmpty { res += self.metadata.description } + + #if DEBUG + res += "{debugID:\(debugID)}" + #endif return res } diff --git a/Sources/DistributedActors/ActorMetadata.swift b/Sources/DistributedActors/ActorMetadata.swift index 635d5ba47..326a1a6c8 100644 --- a/Sources/DistributedActors/ActorMetadata.swift +++ b/Sources/DistributedActors/ActorMetadata.swift @@ -29,11 +29,11 @@ public struct ActorMetadataKeys { } // ==== ---------------------------------------------------------------------------------------------------------------- -// MARK: Pre-defined ActorMetadata keys +// MARK: Metadata Keys: Well Known extension ActorMetadataKeys { internal var path: Key { "$path" } - + /// Actor metadata which impacts how actors with this ID are resolved. /// /// Rather than resolving them by their concrete incarnation (unique id), identifiers with @@ -48,7 +48,18 @@ extension ActorMetadataKeys { /// **WARNING:** Do not use this mechanism for "normal" actors, as it makes their addressess "guessable", /// which is bad from a security and system independence stand point. Please use the cluster receptionist instead. public var wellKnown: Key { "$wellKnown" } +} + +extension ActorID { + internal var isWellKnown: Bool { + self.metadata.wellKnown != nil + } +} + +// ==== ---------------------------------------------------------------------------------------------------------------- +// MARK: Metadata Keys: Type +extension ActorMetadataKeys { /// The type of the distributed actor identified by this ``ActorID``. /// Used only for human radability and debugging purposes, does not participate in equality checks of an actor ID. internal var type: Key { "$type" } // TODO: remove Tag from name diff --git a/Sources/DistributedActors/Cluster/Reception/OperationLogDistributedReceptionist.swift b/Sources/DistributedActors/Cluster/Reception/OperationLogDistributedReceptionist.swift index c0f0c3ac1..164e91d05 100644 --- a/Sources/DistributedActors/Cluster/Reception/OperationLogDistributedReceptionist.swift +++ b/Sources/DistributedActors/Cluster/Reception/OperationLogDistributedReceptionist.swift @@ -235,7 +235,7 @@ public distributed actor OpLogDistributedReceptionist: DistributedReceptionist, var ps = _Props() ps._systemActor = true ps._wellKnown = true - // _knownActorName name is set with @ActorID.Metadata + ps._knownActorName = ActorPath.distributedActorReceptionist.name return ps } @@ -254,6 +254,7 @@ public distributed actor OpLogDistributedReceptionist: DistributedReceptionist, // === listen to cluster events ------------------ self.wellKnownName = ActorPath.distributedActorReceptionist.name + assert(self.id.path.description == "/system/receptionist") // TODO(distributed): remove when we remove paths entirely self.eventsListeningTask = Task.detached { try await self.whenLocal { __secretlyKnownToBeLocal in // TODO(distributed): this is annoying, we must track "known to be local" in typesystem instead diff --git a/Sources/DistributedActors/ClusterSystem.swift b/Sources/DistributedActors/ClusterSystem.swift index e93805d20..0ee3ac024 100644 --- a/Sources/DistributedActors/ClusterSystem.swift +++ b/Sources/DistributedActors/ClusterSystem.swift @@ -983,7 +983,7 @@ extension ClusterSystem { ) } - if let wellKnownName = props._knownActorName { + if let wellKnownName = props._wellKnownName { id.metadata.wellKnown = wellKnownName } @@ -1007,7 +1007,9 @@ extension ClusterSystem { self.namingLock.lock() defer { self.namingLock.unlock() } -// precondition(self._reservedNames.remove(actor.id) != nil, "Attempted to ready an identity that was not reserved: \(actor.id)") + if !actor.id.isWellKnown { + precondition(self._reservedNames.remove(actor.id) != nil, "Attempted to ready an identity that was not reserved: \(actor.id)") + } // Spawn a behavior actor for it: let behavior = InvocationBehavior.behavior(instance: Weak(actor)) diff --git a/Sources/DistributedActors/Props.swift b/Sources/DistributedActors/Props.swift index 2f8cb534f..557a11097 100644 --- a/Sources/DistributedActors/Props.swift +++ b/Sources/DistributedActors/Props.swift @@ -45,6 +45,13 @@ public struct _Props: @unchecked Sendable { /// INTERNAL API: Allows spawning a "well known" actor. Use with great care, /// only if a single incarnation of actor will ever exist under the given path. internal var _wellKnown: Bool = false + + /// Sets the ``ActorMetadataKeys/wellKnown`` key to this name during spawning. + internal var _wellKnownName: String? { + willSet { + self._wellKnown = newValue != nil + } + } /// INTERNAL API: Internal system actor, spawned under the /system namespace. /// This is likely to go away as we remove the actor tree, and move completely to 'distributed actor'.