@@ -173,11 +173,11 @@ import _Concurrency
173173///
174174/// Implementing the remote calls correctly and efficiently is the important task for a distributed actor system library.
175175/// Since those methods are not currently expressible as protocol requirements due to advanced use of generics
176- /// combined with type aliases , they will not appear in the protocol's documentation as explicit requirements.
176+ /// combined with associated types , they will not appear in the protocol's documentation as explicit requirements.
177177/// Instead, we present their signatures that a conforming type has to implement here:
178178///
179179/// > Note: Although the `remoteCall` methods are not expressed as protocol requirements in source,
180- /// > the compiler will provide the same errors as-if they were declared explicitly in this protocol.
180+ /// > the compiler will provide the same errors as-if it was declared explicitly in this protocol.
181181///
182182/// ```swift
183183/// /// Invoked by the Swift runtime when making a remote call.
@@ -280,17 +280,24 @@ public protocol DistributedActorSystem: Sendable {
280280 // ==== ---------------------------------------------------------------------
281281 // - MARK: Resolving actors by identity
282282
283- /// Resolve a local or remote actor address to a real actor instance, or throw if unable to.
283+ /// Resolves a local or remote ``ActorID`` to a reference to given actor, or throws if unable to.
284+ ///
284285 /// The returned value is either a local actor or proxy to a remote actor.
285286 ///
286- /// Resolving an actor is called when a specific distributed actors `init(from:)`
287- /// decoding initializer is invoked. Once the actor's identity is deserialized
288- /// using the `decodeIdentity(from:)` call, it is fed into this function, which
289- /// is responsible for resolving the identity to a remote or local actor reference.
287+ /// This function is not intended to be used directly, but instead is called by the Swift runtime
288+ /// whenever ``DistributedActor/resolve(id:using:)` or a concrete distributed actor's `init(from:)` is invoked.
289+ ///
290+ /// This function should either return an existing actor reference, or `nil` to signal that a remote distributed actor
291+ /// "proxy" should be created for this ``ActorID``. If the resolve fails, meaning that it can neither locate a local
292+ /// actor managed by this actor system, nor identify that the identity is located on some remote actor system, then
293+ /// this function should throw.
294+ ///
295+ /// ```swift
296+ /// distributed actor Worker { /* ... */ }
290297 ///
291- /// If the resolve fails, meaning that it cannot locate a local actor managed for
292- /// this identity, managed by this transport, nor can a remote actor reference
293- /// be created for this identity on this transport, then this function must throw.
298+ /// // the following internally calls actorSystem.resolve(id: id, as: Worker.self)
299+ /// let worker: Worker = try Worker.resolve(id: id, using: actorSystem)
300+ /// ```
294301 ///
295302 /// If this function returns correctly, the returned actor reference is immediately
296303 /// usable. It may not necessarily imply the strict *existence* of a remote actor
@@ -300,13 +307,20 @@ public protocol DistributedActorSystem: Sendable {
300307 ///
301308 /// Detecting liveness of such remote actors shall be offered / by transport libraries
302309 /// by other means, such as "watching an actor for termination" or similar.
310+ ///
311+ /// - Parameter id: The `ActorID` to resolve an actor reference for
312+ /// - Parameter actorType: The type of distributed actor the ID is expected to point at.
313+ ///
314+ /// - Throws: When unable to confirm if the `id` is correct, the resolved actor does not match the expected `actorType`,
315+ /// or any other internal validation error within the actor system's resolve process occurs.
303316 func resolve< Act> ( id: ActorID , as actorType: Act . Type ) throws -> Act ?
304317 where Act: DistributedActor ,
305318 Act. ID == ActorID
306319
307320 // ==== ---------------------------------------------------------------------
308321 // - MARK: Actor Lifecycle
309- /// Create an `ActorID` for the passed actor type.
322+
323+ /// Assign an ``ActorID`` for the passed actor type.
310324 ///
311325 /// This function is invoked by an distributed actor during its initialization,
312326 /// and the returned address value is stored along with it for the time of its
@@ -326,10 +340,10 @@ public protocol DistributedActorSystem: Sendable {
326340 /// mapping for the purpose of implementing the `resolve(id:as:)` method.
327341 ///
328342 /// The system usually should NOT retain the passed reference, and it will be informed via
329- /// `resignID(_:)` when the actor has been deallocated so it can remove the stale reference from its
343+ /// `` resignID(_:)` ` when the actor has been deallocated so it can remove the stale reference from its
330344 /// internal `ActorID: DistributedActor` mapping.
331345 ///
332- /// The `actor. id` of the passed actor must be an `ActorID` that this system previously has assigned.
346+ /// The ``DistributedActor/ id`` of the passed actor must be an `` ActorID` ` that this system previously has assigned.
333347 ///
334348 /// If `actorReady` gets called with some unknown ID, it should crash immediately as it signifies some
335349 /// very unexpected use of the system.
@@ -688,6 +702,32 @@ func _executeDistributedTarget<D: DistributedTargetInvocationDecoder>(
688702/// Once encoded, the system should use some underlying transport mechanism to send the
689703/// bytes serialized by the invocation to the remote peer.
690704///
705+ /// ### Protocol requirements
706+ /// Similar to the ``DistributedActorSystem`` and its `remoteCall` and `remoteCallVoid` protocol requirements,
707+ /// the `DistributedTargetInvocationEncoder` contains a few methods which are not possible to express in source due to
708+ /// advanced use of generics combined with associated types. Specifically, the `recordArgument` and `recordReturnType`
709+ /// methods are not expressed in source as protocol requirements, but will be treated by the compiler as-if they were.
710+ ///
711+ /// > Note: Although the `recordArgument` method is not expressed as protocol requirement in source,
712+ /// > the compiler will provide the same errors as-if it was declared explicitly in this protocol.
713+ ///
714+ /// In addition to the compiler offering compile errors if those witnesses are missing in an adopting type,
715+ /// we present their signatures here for reference:
716+ ///
717+ /// ```swift
718+ /// /// Record an argument of `Argument` type.
719+ /// /// This will be invoked for every argument of the target, in declaration order.
720+ /// mutating func recordArgument<Value: SerializationRequirement>(
721+ /// _ argument: DistributedTargetArgument<Value>
722+ /// ) throws
723+ ///
724+ /// /// Ad-hoc requirement
725+ /// ///
726+ /// /// Record the return type of the distributed method.
727+ /// /// This method will not be invoked if the target is returning `Void`.
728+ /// mutating func recordReturnType<R: SerializationRequirement>(_ type: R.Type) throws
729+ /// ```
730+ ///
691731/// ## Decoding an invocation
692732/// Since every actor system is going to deal with a concrete invocation type, they may
693733/// implement decoding them whichever way is most optimal for the given system.
@@ -700,10 +740,13 @@ func _executeDistributedTarget<D: DistributedTargetInvocationDecoder>(
700740/// entry points on the provided types.
701741@available( SwiftStdlib 5.7 , * )
702742public protocol DistributedTargetInvocationEncoder {
743+ /// The serialization requirement that the types passed to `recordArgument` and `recordReturnType` are required to conform to.
703744 associatedtype SerializationRequirement
704745
705746 /// The arguments must be encoded order-preserving, and once `decodeGenericSubstitutions`
706747 /// is called, the substitutions must be returned in the same order in which they were recorded.
748+ ///
749+ /// - Parameter type: a generic substitution type to be recorded for this invocation.
707750 mutating func recordGenericSubstitution< T> ( _ type: T . Type ) throws
708751
709752// /// Ad-hoc requirement
@@ -716,6 +759,8 @@ public protocol DistributedTargetInvocationEncoder {
716759
717760 /// Record the error type of the distributed method.
718761 /// This method will not be invoked if the target is not throwing.
762+ ///
763+ /// - Parameter type: the type of error that was declared to be thrown by the invocation target. Currently this can only ever be `Error.self`.
719764 mutating func recordErrorType< E: Error > ( _ type: E . Type ) throws
720765
721766// /// Ad-hoc requirement
@@ -724,6 +769,10 @@ public protocol DistributedTargetInvocationEncoder {
724769// /// This method will not be invoked if the target is returning `Void`.
725770// mutating func recordReturnType<R: SerializationRequirement>(_ type: R.Type) throws
726771
772+ /// Invoked to signal to the encoder that no further `record...` calls will be made on it.
773+ ///
774+ /// Useful if the encoder needs to perform some "final" task before the underlying message is considered complete,
775+ /// e.g. computing a checksum, or some additional message signing or finalization step.
727776 mutating func do neRecording( ) throws
728777}
729778
@@ -771,10 +820,48 @@ public struct RemoteCallArgument<Value> {
771820
772821/// Decoder that must be provided to `executeDistributedTarget` and is used
773822/// by the Swift runtime to decode arguments of the invocation.
823+ ///
824+ /// ### Protocol requirements
825+ /// Similar to the ``DistributedTargetInvocationEncoder`` and its `recordArgument` and `recordReturnType` protocol requirements,
826+ /// the `DistributedTargetInvocationDecoder` contains a method which is not possible to express in source due to
827+ /// advanced use of generics combined with associated types. Specifically, the `decodeNextArgument`
828+ /// method is not expressed in source as protocol requirement, but will be treated by the compiler as-if it was.
829+ ///
830+ /// > Note: Although the `decodeNextArgument` method is not expressed as protocol requirement in source,
831+ /// > the compiler will provide the same errors as-if it was declared explicitly in this protocol.
832+ ///
833+ /// In addition to the compiler offering compile errors if this witness is missing in an adopting type,
834+ /// we present its signature here for reference:
835+ ///
836+ /// ```swift
837+ /// /// Ad-hoc protocol requirement
838+ /// ///
839+ /// /// Attempt to decode the next argument from the underlying buffers into pre-allocated storage
840+ /// /// pointed at by 'pointer'.
841+ /// ///
842+ /// /// This method should throw if it has no more arguments available, if decoding the argument failed,
843+ /// /// or, optionally, if the argument type we're trying to decode does not match the stored type.
844+ /// ///
845+ /// /// The result of the decoding operation must be stored into the provided 'pointer' rather than
846+ /// /// returning a value. This pattern allows the runtime to use a heavily optimized, pre-allocated
847+ /// /// buffer for all the arguments and their expected types. The 'pointer' passed here is a pointer
848+ /// /// to a "slot" in that pre-allocated buffer. That buffer will then be passed to a thunk that
849+ /// /// performs the actual distributed (local) instance method invocation.
850+ /// mutating func decodeNextArgument<Argument: SerializationRequirement>() throws -> Argument
851+ /// ```
774852@available ( SwiftStdlib 5 . 7 , * )
775853public protocol DistributedTargetInvocationDecoder {
854+ /// The serialization requirement that the types passed to `decodeNextArgument` are required to conform to.
855+ /// The type returned by `decodeReturnType` is also expected to conform to this associated type requirement.
776856 associatedtype SerializationRequirement
777857
858+ /// Decode all generic substitutions that were recorded for this invocation.
859+ ///
860+ /// The values retrieved from here must be in the same order as they were recorded by
861+ /// ``DistributedTargetInvocationEncoder/recordGenericSubstitution(_:)``.
862+ ///
863+ /// - Returns: array of all generic substitutions necessary to execute this invocation target.
864+ /// - Throws: if decoding substitutions fails.
778865 mutating func decodeGenericSubstitutions( ) throws -> [ Any . Type ]
779866
780867// /// Ad-hoc protocol requirement
@@ -792,6 +879,10 @@ public protocol DistributedTargetInvocationDecoder {
792879// /// performs the actual distributed (local) instance method invocation.
793880// mutating func decodeNextArgument<Argument: SerializationRequirement>() throws -> Argument
794881
882+ /// Decode the specific error type that the distributed invocation target has recorded.
883+ /// Currently this effectively can only ever be `Error.self`.
884+ ///
885+ /// If the target known to not be throwing, or no error type was recorded, the method should return `nil`.
795886 mutating func decodeErrorType( ) throws -> Any . Type ?
796887
797888 /// Attempt to decode the known return type of the distributed invocation.
@@ -801,15 +892,51 @@ public protocol DistributedTargetInvocationDecoder {
801892 mutating func decodeReturnType( ) throws -> Any . Type ?
802893}
803894
895+ /// Protocol a distributed invocation execution's result handler.
896+ ///
897+ /// An instance conforming to this type must be passed when invoking
898+ /// ``executeDistributedTarget(on:target:invocationDecoder:handler:)`` while handling an incoming distributed call.
899+ ///
900+ /// The handler will then be invoked with the return value (or error) that the invoked target returned (or threw).
901+ ///
902+ /// ### Protocol requirements
903+ /// Similar to the ``DistributedActorSystem`` and its `remoteCall` and `remoteCallVoid` protocol requirements,
904+ /// the `DistributedTargetInvocationResultHandler` contains a method which is not possible to express in source due to
905+ /// advanced use of generics combined with associated types. Specifically, the `onReturn` method is not expressed in
906+ /// source as protocol requirement, but will be treated by the compiler as-if they were.
907+ ///
908+ /// > Note: Although the `onReturn` method is not expressed as protocol requirement in source,
909+ /// > the compiler will provide the same errors as-if it was declared explicitly in this protocol.
910+ ///
911+ /// In addition to the compiler offering compile errors if this witnesses is missing in an adopting type,
912+ /// we present its signature here for reference:
913+ ///
914+ /// ```swift
915+ /// /// Ad-hoc protocol requirement
916+ /// ///
917+ /// /// Invoked when the distributed target execution returns successfully.
918+ /// /// The `value` is the return value of the executed distributed invocation target.
919+ /// func onReturn<Success: SerializationRequirement>(value: Success) async throws
920+ /// ```
804921@available ( SwiftStdlib 5 . 7 , * )
805922public protocol DistributedTargetInvocationResultHandler {
923+ /// The serialization requirement that the value passed to `onReturn` is required to conform to.
806924 associatedtype SerializationRequirement
925+
926+ // /// Ad-hoc protocol requirement
927+ // ///
928+ // /// Invoked when the distributed target execution returns successfully.
929+ // /// The `value` is the return value of the executed distributed invocation target.
807930// func onReturn<Success: SerializationRequirement>(value: Success) async throws
808931
809- /// Invoked when the distributed target invocation of a `Void` returning
932+ /// Invoked when the distributed target execution of a `Void` returning
810933 /// function has completed successfully.
811934 func onReturnVoid( ) async throws
812935
936+ /// Invoked when the distributed target execution of a target has thrown an error.
937+ ///
938+ /// It is not guaranteed that the error conform to the ``SerializationRequirement``;
939+ /// This guarantee is only given to return values (and offered by `onReturn`).
813940 func onThrow< Err: Error > ( error: Err ) async throws
814941}
815942
0 commit comments