1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -parse-as-library) | %FileCheck %s
// REQUIRES: executable_test
// REQUIRES: concurrency
// REQUIRES: distributed
// rdar://76038845
// UNSUPPORTED: use_os_stdlib
// UNSUPPORTED: back_deployment_runtime
import Distributed
distributed actor SomeSpecificDistributedActor {
deinit {
print("deinit \(self.id)")
}
}
// ==== Fake Transport ---------------------------------------------------------
struct FakeActorID: Sendable, Hashable, Codable {
let id: UInt64
}
enum FakeActorSystemError: DistributedActorSystemError {
case unsupportedActorIdentity(Any)
}
struct ActorAddress: Sendable, Hashable, Codable {
let address: String
init(parse address : String) {
self.address = address
}
}
final class FakeActorSystem: DistributedActorSystem {
typealias ActorID = ActorAddress
typealias InvocationDecoder = FakeInvocation
typealias InvocationEncoder = FakeInvocation
typealias SerializationRequirement = Codable
typealias ResultHandler = FakeResultHandler
deinit {
print("deinit \(self)")
}
func resolve<Act>(id: ActorID, as actorType: Act.Type)
throws -> Act?
where Act: DistributedActor {
return nil
}
func assignID<Act>(_ actorType: Act.Type) -> ActorID
where Act: DistributedActor {
let id = ActorAddress(parse: "xxx")
print("assignID type:\(actorType), id:\(id)")
return id
}
func actorReady<Act>(_ actor: Act)
where Act: DistributedActor,
Act.ID == ActorID {
print("actorReady actor:\(actor), id:\(actor.id)")
}
func resignID(_ id: ActorID) {
print("assignID id:\(id)")
}
func makeInvocationEncoder() -> InvocationEncoder {
.init()
}
func remoteCall<Act, Err, Res>(
on actor: Act,
target: RemoteCallTarget,
invocation invocationEncoder: inout InvocationEncoder,
throwing: Err.Type,
returning: Res.Type
) async throws -> Res
where Act: DistributedActor,
Act.ID == ActorID,
Err: Error,
Res: SerializationRequirement {
fatalError("Not implemented")
}
func remoteCallVoid<Act, Err>(
on actor: Act,
target: RemoteCallTarget,
invocation invocationEncoder: inout InvocationEncoder,
throwing: Err.Type
) async throws
where Act: DistributedActor,
Act.ID == ActorID,
Err: Error {
fatalError("Not implemented")
}
}
class FakeInvocation: DistributedTargetInvocationEncoder, DistributedTargetInvocationDecoder {
typealias SerializationRequirement = Codable
func recordGenericSubstitution<T>(_ type: T.Type) throws {}
func recordArgument<Value: SerializationRequirement>(_ argument: RemoteCallArgument<Value>) throws {}
func recordReturnType<R: SerializationRequirement>(_ type: R.Type) throws {}
func recordErrorType<E: Error>(_ type: E.Type) throws {}
func doneRecording() throws {}
// === Receiving / decoding -------------------------------------------------
func decodeGenericSubstitutions() throws -> [Any.Type] { [] }
func decodeNextArgument<Argument: SerializationRequirement>() throws -> Argument{ fatalError() }
func decodeReturnType() throws -> Any.Type? { nil }
func decodeErrorType() throws -> Any.Type? { nil }
}
public struct FakeResultHandler: DistributedTargetInvocationResultHandler {
public typealias SerializationRequirement = Codable
public func onReturn<Success: SerializationRequirement>(value: Success) async throws {
fatalError("Not implemented: \(#function)")
}
public func onReturnVoid() async throws {
fatalError("Not implemented: \(#function)")
}
public func onThrow<Err: Error>(error: Err) async throws {
fatalError("Not implemented: \(#function)")
}
}
typealias DefaultDistributedActorSystem = FakeActorSystem
// ==== Execute ----------------------------------------------------------------
func test_remote() async {
let address = ActorAddress(parse: "sact://127.0.0.1/example#1234")
var system: FakeActorSystem? = FakeActorSystem()
let remote = try! SomeSpecificDistributedActor.resolve(id: address, using: system!)
system = nil
print("done") // CHECK: done
print("remote.id = \(remote.id)") // CHECK: remote.id = ActorAddress(address: "sact://127.0.0.1/example#1234")
print("remote.system = \(remote.actorSystem)") // CHECK: remote.system = main.FakeActorSystem
// system must deinit after the last actor using it does deinit
// CHECK-DAG: deinit main.FakeActorSystem
}
@main struct Main {
static func main() async {
await test_remote()
}
}
|