@@ -172,23 +172,21 @@ extension DistributedActorSystem {
172172 /// latency sensitive-use-cases.
173173 public func executeDistributedTarget< Act, ResultHandler> (
174174 on actor : Act ,
175- mangledTargetName : String ,
175+ target : RemoteCallTarget ,
176176 invocationDecoder: inout InvocationDecoder ,
177177 handler: ResultHandler
178178 ) async throws where Act: DistributedActor ,
179179 // Act.ID == ActorID, // FIXME(distributed): can we bring this back?
180180 ResultHandler: DistributedTargetInvocationResultHandler {
181- // NOTE: this implementation is not the most efficient, nor final, version of this func
182- // we end up demangling the name multiple times, perform more heap allocations than
183- // we truly need to etc. We'll eventually move this implementation to a specialized one
184- // avoiding these issues.
185- guard mangledTargetName. count > 0 && mangledTargetName. first == " $ " else {
186- throw ExecuteDistributedTargetError (
187- message: " Illegal mangledTargetName detected, must start with '$' " )
188- }
181+ // NOTE: Implementation could be made more efficient because we still risk
182+ // demangling a RemoteCallTarget identity (if it is a mangled name) multiple
183+ // times. We would prefer to store if it is a mangled name, demangle, and
184+ // always refer to that demangled repr perhaps? We do cache the resulting
185+ // pretty formatted name of the call target, but perhaps we can do better.
189186
190187 // Get the expected parameter count of the func
191- let nameUTF8 = Array ( mangledTargetName. utf8)
188+ let targetName = target. identifier
189+ let nameUTF8 = Array ( targetName. utf8)
192190
193191 // Gen the generic environment (if any) associated with the target.
194192 let genericEnv = nameUTF8. withUnsafeBufferPointer { nameUTF8 in
@@ -207,7 +205,9 @@ extension DistributedActorSystem {
207205
208206 if let genericEnv = genericEnv {
209207 let subs = try invocationDecoder. decodeGenericSubstitutions ( )
210-
208+ for item in subs {
209+ print ( " SUB: \( item) " )
210+ }
211211 if subs. isEmpty {
212212 throw ExecuteDistributedTargetError (
213213 message: " Cannot call generic method without generic argument substitutions " )
@@ -224,7 +224,7 @@ extension DistributedActorSystem {
224224 genericArguments: substitutionsBuffer!)
225225 if numWitnessTables < 0 {
226226 throw ExecuteDistributedTargetError (
227- message: " Generic substitutions \( subs) do not satisfy generic requirements of \( mangledTargetName ) " )
227+ message: " Generic substitutions \( subs) do not satisfy generic requirements of \( target ) ( \( targetName ) ) " )
228228 }
229229 }
230230
@@ -237,7 +237,7 @@ extension DistributedActorSystem {
237237 message: """
238238 Failed to decode distributed invocation target expected parameter count,
239239 error code: \( paramCount)
240- mangled name: \( mangledTargetName )
240+ mangled name: \( targetName )
241241 """ )
242242 }
243243
@@ -262,7 +262,7 @@ extension DistributedActorSystem {
262262 message: """
263263 Failed to decode the expected number of params of distributed invocation target, error code: \( decodedNum)
264264 (decoded: \( decodedNum) , expected params: \( paramCount)
265- mangled name: \( mangledTargetName )
265+ mangled name: \( targetName )
266266 """ )
267267 }
268268
@@ -280,7 +280,7 @@ extension DistributedActorSystem {
280280 return UnsafeRawPointer ( UnsafeMutablePointer< R> . allocate( capacity: 1 ) )
281281 }
282282
283- guard let returnTypeFromTypeInfo: Any . Type = _getReturnTypeInfo ( mangledMethodName: mangledTargetName ,
283+ guard let returnTypeFromTypeInfo: Any . Type = _getReturnTypeInfo ( mangledMethodName: targetName ,
284284 genericEnv: genericEnv,
285285 genericArguments: substitutionsBuffer) else {
286286 throw ExecuteDistributedTargetError (
@@ -307,7 +307,7 @@ extension DistributedActorSystem {
307307 // Execute the target!
308308 try await _executeDistributedTarget (
309309 on: actor ,
310- mangledTargetName , UInt ( mangledTargetName . count) ,
310+ targetName , UInt ( targetName . count) ,
311311 argumentDecoder: & invocationDecoder,
312312 argumentTypes: argumentTypesBuffer. baseAddress!. _rawValue,
313313 resultBuffer: resultBuffer. _rawValue,
@@ -326,6 +326,43 @@ extension DistributedActorSystem {
326326 }
327327}
328328
329+ /// Represents a 'target' of a distributed call, such as a `distributed func` or
330+ /// `distributed` computed property. Identification schemes may vary between
331+ /// systems, and are subject to evolution.
332+ ///
333+ /// Actor systems generally should treat the `identifier` as an opaque string,
334+ /// and pass it along to the remote system for in their `remoteCall`
335+ /// implementation. Alternative approaches are possible, where the identifiers
336+ /// are either compressed, cached, or represented in other ways, as long as the
337+ /// recipient system is able to determine which target was intended to be
338+ /// invoked.
339+ ///
340+ /// The string representation will attempt to pretty print the target identifier,
341+ /// however its exact format is not specified and may change in future versions.
342+ @available ( SwiftStdlib 5 . 7 , * )
343+ public struct RemoteCallTarget : CustomStringConvertible {
344+ private let _identifier : String
345+
346+ public init ( _ identifier: String ) {
347+ self . _identifier = identifier
348+ }
349+
350+ /// The underlying identifier of the target, returned as-is.
351+ public var identifier : String {
352+ return _identifier
353+ }
354+
355+ /// Attempts to pretty format the underlying target identifier.
356+ /// If unable to, returns the raw underlying identifier.
357+ public var description : String {
358+ if let name = _getFunctionFullNameFromMangledName ( mangledName: _identifier) {
359+ return name
360+ } else {
361+ return " \( _identifier) "
362+ }
363+ }
364+ }
365+
329366@available ( SwiftStdlib 5 . 7 , * )
330367@_silgen_name ( " swift_distributed_execute_target " )
331368func _executeDistributedTarget< D: DistributedTargetInvocationDecoder > (
@@ -339,29 +376,6 @@ func _executeDistributedTarget<D: DistributedTargetInvocationDecoder>(
339376 numWitnessTables: UInt
340377) async throws
341378
342- // ==== ----------------------------------------------------------------------------------------------------------------
343- // MARK: Support types
344- /// A distributed 'target' can be a `distributed func` or `distributed` computed property.
345- @available( SwiftStdlib 5.7 , * )
346- public struct RemoteCallTarget { // TODO: ship this around always; make printing nice
347- let _mangledName : String // TODO: StaticString would be better here; no arc, codesize of cleanups
348-
349- // Only intended to be created by the _Distributed library.
350- // TODO(distributed): make this internal and only allow calling by the synthesized code?
351- public init( _mangledName: String) {
352- self . _mangledName = _mangledName
353- }
354-
355- public var mangledName : String {
356- _mangledName
357- }
358-
359- // <module>.Base.hello(hi:)
360- public var fullName : String { // TODO: make description
361- fatalError ( " NOT IMPLEMENTED YET: \( #function) " )
362- }
363- }
364-
365379/// Used to encode an invocation of a distributed target (method or computed property).
366380///
367381/// ## Forming an invocation
@@ -407,11 +421,9 @@ public protocol DistributedTargetInvocationEncoder {
407421// mutating func recordArgument<Argument: SerializationRequirement>(_ argument: Argument) throws
408422 // TODO(distributed): offer recordArgument(label:type:)
409423
410- // /// Ad-hoc requirement
411- // ///
412- // /// Record the error type of the distributed method.
413- // /// This method will not be invoked if the target is not throwing.
414- // mutating func recordErrorType<E: Error>(_ type: E.Type) throws // TODO: make not adhoc
424+ /// Record the error type of the distributed method.
425+ /// This method will not be invoked if the target is not throwing.
426+ mutating func recordErrorType< E: Error > ( _ type: E . Type ) throws
415427
416428// /// Ad-hoc requirement
417429// ///
0 commit comments