mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
* [Distributed] dist actor always has default executor (currently) * [Distributed] extra test for missing makeEncoder * [DistributedDecl] Add DistributedActorSystem to known SDK types * [DistributedActor] ok progress on getting the system via witness * [Distributed] allow hop-to `let any: any X` where X is DistActor * [Distributed] AST: Add an accessor to determine whether type is distributed actor - Classes have specialized method on their declarations - Archetypes and existentials check their conformances for presence of `DistributedActor` protocol. * [Distributed] AST: Account for distributed members declared in class extensions `getConcreteReplacementForProtocolActorSystemType` should use `getSelfClassDecl` otherwise it wouldn't be able to find actor if the member is declared in an extension. * [Distributed] fix ad-hoc requirement checks for 'mutating' [PreChecker] LookupDC might be null, so account for that * [Distributed] Completed AST synthesis for dist thunk * [Distributed][ASTDumper] print pretty distributed in right color in AST dumps * wip on making the local/remote calls * using the _local to mark the localCall as known local * [Distributed] fix passing Never when not throwing * fix lifetime of mangled string * [Distributed] Implement recordGenericSubstitution * [Distributed] Dont add . * [Distributed] dont emit thunk when func broken * [Distributed] fix tests; cleanups * [Distributed] cleanup, move is... funcs to DistributedDecl * [Distributed] Remove SILGen for distributed thunks, it is in Sema now! * [Distributed] no need to check stored props in protocols * remote not used flag * fix mangling test * [Distributed] Synthesis: Don't re-use AST nodes for `decodeArgument` references * [Distributed] Synthesis: Make sure that each thunk parameter has an internal name * [Distributed/Synthesis] NFC: Add a comment regarding empty internal parameter names * [Distributed] NFC: Adjust distributed thunk manglings in the accessor section test-cases * cleanup * [Distributed] NFC: Adjust distributed thunk manglings in the accessor thunk test-cases * review follow ups * xfail some linux tests for now so we can land the AST thunk * Update distributed_actor_remote_functions.swift Co-authored-by: Pavel Yaskevich <xedin@apache.org>
153 lines
5.7 KiB
Swift
153 lines
5.7 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2020 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import Swift
|
|
import _Concurrency
|
|
|
|
// ==== Distributed Actor -----------------------------------------------------
|
|
|
|
/// Common protocol to which all distributed actors conform implicitly.
|
|
///
|
|
/// It is not possible to conform to this protocol manually explicitly.
|
|
/// Only a 'distributed actor' declaration or protocol with 'DistributedActor'
|
|
/// requirement may conform to this protocol.
|
|
///
|
|
/// The 'DistributedActor' protocol provides the core functionality of any
|
|
/// distributed actor.
|
|
@available(SwiftStdlib 5.7, *)
|
|
public protocol DistributedActor:
|
|
AnyActor,
|
|
Identifiable,
|
|
Hashable, Codable
|
|
where ID == ActorSystem.ActorID {
|
|
|
|
/// The type of transport used to communicate with actors of this type.
|
|
associatedtype ActorSystem: DistributedActorSystem
|
|
|
|
/// The serialization requirement to apply to all distributed declarations inside the actor.
|
|
typealias SerializationRequirement = ActorSystem.SerializationRequirement
|
|
|
|
/// Logical identity of this distributed actor.
|
|
///
|
|
/// Many distributed actor references may be pointing at, logically, the same actor.
|
|
/// For example, calling `resolve(id:using:)` multiple times, is not guaranteed
|
|
/// to return the same exact resolved actor instance, however all the references would
|
|
/// represent logically references to the same distributed actor, e.g. on a different node.
|
|
///
|
|
/// Conformance to this requirement is synthesized automatically for any
|
|
/// `distributed actor` declaration.
|
|
nonisolated override var id: ID { get }
|
|
|
|
/// The `ActorSystem` that is managing this distributed actor.
|
|
///
|
|
/// It is immutable and equal to the system passed in the local/resolve
|
|
/// initializer.
|
|
///
|
|
/// Conformance to this requirement is synthesized automatically for any
|
|
/// `distributed actor` declaration.
|
|
nonisolated var actorSystem: ActorSystem { get }
|
|
|
|
/// Resolves the passed in `id` against the `system`, returning
|
|
/// either a local or remote actor reference.
|
|
///
|
|
/// The system will be asked to `resolve` the identity and return either
|
|
/// a local instance or request a proxy to be created for this identity.
|
|
///
|
|
/// A remote distributed actor reference will forward all invocations through
|
|
/// the system, allowing it to take over the remote messaging with the
|
|
/// remote actor instance.
|
|
///
|
|
/// - Parameter id: identity uniquely identifying a, potentially remote, actor in the system
|
|
/// - Parameter system: `system` which should be used to resolve the `identity`, and be associated with the returned actor
|
|
static func resolve(id: ID, using system: ActorSystem) throws -> Self
|
|
}
|
|
|
|
// ==== Hashable conformance ---------------------------------------------------
|
|
|
|
@available(SwiftStdlib 5.7, *)
|
|
extension DistributedActor {
|
|
nonisolated public func hash(into hasher: inout Hasher) {
|
|
self.id.hash(into: &hasher)
|
|
}
|
|
|
|
nonisolated public static func ==(lhs: Self, rhs: Self) -> Bool {
|
|
lhs.id == rhs.id
|
|
}
|
|
}
|
|
|
|
// ==== Codable conformance ----------------------------------------------------
|
|
|
|
extension CodingUserInfoKey {
|
|
@available(SwiftStdlib 5.7, *)
|
|
public static let actorSystemKey = CodingUserInfoKey(rawValue: "$distributed_actor_system")!
|
|
}
|
|
|
|
@available(SwiftStdlib 5.7, *)
|
|
extension DistributedActor {
|
|
nonisolated public init(from decoder: Decoder) throws {
|
|
guard let system = decoder.userInfo[.actorSystemKey] as? ActorSystem else {
|
|
throw DistributedActorCodingError(message:
|
|
"Missing system (for key .actorSystemKey) " +
|
|
"in Decoder.userInfo, while decoding \(Self.self).")
|
|
}
|
|
|
|
let id: ID = try Self.ID(from: decoder)
|
|
self = try Self.resolve(id: id, using: system)
|
|
}
|
|
|
|
nonisolated public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.singleValueContainer()
|
|
try container.encode(self.id)
|
|
}
|
|
}
|
|
|
|
// ==== Local actor special handling -------------------------------------------
|
|
|
|
@available(SwiftStdlib 5.7, *)
|
|
extension DistributedActor {
|
|
|
|
/// Executes the passed 'body' only when the distributed actor is local instance.
|
|
///
|
|
/// The `Self` passed to the the body closure is isolated, meaning that the
|
|
/// closure can be used to call non-distributed functions, or even access actor
|
|
/// state.
|
|
///
|
|
/// When the actor is remote, the closure won't be executed and this function will return nil.
|
|
public nonisolated func whenLocal<T: Sendable>(
|
|
_ body: @Sendable (isolated Self) async throws -> T
|
|
) async rethrows -> T? {
|
|
if __isLocalActor(self) {
|
|
return try await body(self)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/************************* Runtime Functions **********************************/
|
|
/******************************************************************************/
|
|
|
|
// ==== isRemote / isLocal -----------------------------------------------------
|
|
|
|
@_silgen_name("swift_distributed_actor_is_remote")
|
|
public func __isRemoteActor(_ actor: AnyObject) -> Bool
|
|
|
|
public func __isLocalActor(_ actor: AnyObject) -> Bool {
|
|
return !__isRemoteActor(actor)
|
|
}
|
|
|
|
// ==== Proxy Actor lifecycle --------------------------------------------------
|
|
|
|
@_silgen_name("swift_distributedActor_remote_initialize")
|
|
func _distributedActorRemoteInitialize(_ actorType: Builtin.RawPointer) -> Any
|