mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
142 lines
4.1 KiB
Swift
142 lines
4.1 KiB
Swift
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -Xfrontend -enable-experimental-distributed -parse-as-library) | %FileCheck %s --dump-input=always
|
|
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: concurrency
|
|
// REQUIRES: distributed
|
|
|
|
// rdar://76038845
|
|
// UNSUPPORTED: use_os_stdlib
|
|
// UNSUPPORTED: back_deployment_runtime
|
|
|
|
// FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574
|
|
// UNSUPPORTED: windows
|
|
|
|
import _Distributed
|
|
|
|
distributed actor Capybara {
|
|
// only the local capybara can do this!
|
|
func eat() -> String {
|
|
"watermelon"
|
|
}
|
|
}
|
|
|
|
|
|
// ==== Fake Transport ---------------------------------------------------------
|
|
struct ActorAddress: Sendable, Hashable, Codable {
|
|
let address: String
|
|
init(parse address: String) {
|
|
self.address = address
|
|
}
|
|
}
|
|
|
|
struct FakeActorSystem: DistributedActorSystem {
|
|
typealias ActorID = ActorAddress
|
|
typealias InvocationDecoder = FakeInvocation
|
|
typealias InvocationEncoder = FakeInvocation
|
|
typealias SerializationRequirement = Codable
|
|
|
|
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")
|
|
return id
|
|
}
|
|
|
|
func actorReady<Act>(_ actor: Act)
|
|
where Act: DistributedActor,
|
|
Act.ID == ActorID {
|
|
}
|
|
|
|
func resignID(_ id: ActorID) {
|
|
}
|
|
|
|
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,
|
|
Err: Error,
|
|
// Act.ID == ActorID,
|
|
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,
|
|
Err: Error
|
|
// Act.ID == ActorID
|
|
{
|
|
fatalError("Not implemented")
|
|
}
|
|
}
|
|
|
|
struct FakeInvocation: DistributedTargetInvocationEncoder, DistributedTargetInvocationDecoder {
|
|
typealias SerializationRequirement = Codable
|
|
|
|
mutating func recordGenericSubstitution<T>(_ type: T.Type) throws {}
|
|
mutating func recordArgument<Argument: SerializationRequirement>(_ argument: Argument) throws {}
|
|
mutating func recordReturnType<R: SerializationRequirement>(_ type: R.Type) throws {}
|
|
mutating func recordErrorType<E: Error>(_ type: E.Type) throws {}
|
|
mutating func doneRecording() throws {}
|
|
|
|
// === Receiving / decoding -------------------------------------------------
|
|
|
|
func decodeGenericSubstitutions() throws -> [Any.Type] { [] }
|
|
mutating func decodeNextArgument<Argument>(
|
|
_ argumentType: Argument.Type,
|
|
into pointer: UnsafeMutablePointer<Argument> // pointer to our hbuffer
|
|
) throws { /* ... */ }
|
|
func decodeReturnType() throws -> Any.Type? { nil }
|
|
func decodeErrorType() throws -> Any.Type? { nil }
|
|
|
|
struct FakeArgumentDecoder: DistributedTargetInvocationArgumentDecoder {
|
|
typealias SerializationRequirement = Codable
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.5, *)
|
|
typealias DefaultDistributedActorSystem = FakeActorSystem
|
|
|
|
func test() async throws {
|
|
let system = DefaultDistributedActorSystem()
|
|
|
|
let local = Capybara(system: system)
|
|
// await local.eat() // SHOULD ERROR
|
|
let valueWhenLocal: String? = await local.whenLocal { __secretlyKnownToBeLocal in
|
|
__secretlyKnownToBeLocal.eat()
|
|
}
|
|
|
|
// CHECK: valueWhenLocal: watermelon
|
|
print("valueWhenLocal: \(valueWhenLocal ?? "nil")")
|
|
|
|
let remote = try Capybara.resolve(id: local.id, using: system)
|
|
let valueWhenRemote: String? = await remote.whenLocal { __secretlyKnownToBeLocal in
|
|
__secretlyKnownToBeLocal.eat()
|
|
}
|
|
|
|
// CHECK: valueWhenRemote: nil
|
|
print("valueWhenRemote: \(valueWhenRemote ?? "nil")")
|
|
}
|
|
|
|
@main struct Main {
|
|
static func main() async {
|
|
try! await test()
|
|
}
|
|
}
|