mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Distributed] move _missingDistributedActorTransport to _Distributed
This commit is contained in:
@@ -88,7 +88,4 @@ FUNC_DECL(Swap, "swap")
|
|||||||
FUNC_DECL(UnimplementedInitializer, "_unimplementedInitializer")
|
FUNC_DECL(UnimplementedInitializer, "_unimplementedInitializer")
|
||||||
FUNC_DECL(Undefined, "_undefined")
|
FUNC_DECL(Undefined, "_undefined")
|
||||||
|
|
||||||
// TODO: move to _Distributed
|
|
||||||
FUNC_DECL(MissingDistributedActorTransport, "_missingDistributedActorTransport")
|
|
||||||
|
|
||||||
#undef FUNC_DECL
|
#undef FUNC_DECL
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
# define KNOWN_SDK_FUNC_DECL(Module, Name, Id)
|
# define KNOWN_SDK_FUNC_DECL(Module, Name, Id)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//KNOWN_SDK_FUNC_DECL(Distributed, MissingDistributedActorTransport, "_missingDistributedActorTransport")
|
KNOWN_SDK_FUNC_DECL(Distributed, MissingDistributedActorTransport, "_missingDistributedActorTransport")
|
||||||
KNOWN_SDK_FUNC_DECL(Distributed, IsRemoteDistributedActor, "__isRemoteActor")
|
KNOWN_SDK_FUNC_DECL(Distributed, IsRemoteDistributedActor, "__isRemoteActor")
|
||||||
|
|
||||||
#undef KNOWN_SDK_FUNC_DECL
|
#undef KNOWN_SDK_FUNC_DECL
|
||||||
|
|||||||
@@ -561,9 +561,11 @@ static void addImplicitDistributedActorStoredProperties(ClassDecl *decl) {
|
|||||||
///
|
///
|
||||||
/// Create a stub body that emits a fatal error message.
|
/// Create a stub body that emits a fatal error message.
|
||||||
static std::pair<BraceStmt *, bool>
|
static std::pair<BraceStmt *, bool>
|
||||||
synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *) {
|
synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *context) {
|
||||||
|
auto distributedFunc = static_cast<AbstractFunctionDecl *>(context);
|
||||||
auto classDecl = func->getDeclContext()->getSelfClassDecl();
|
auto classDecl = func->getDeclContext()->getSelfClassDecl();
|
||||||
auto &ctx = func->getASTContext();
|
auto &ctx = func->getASTContext();
|
||||||
|
auto &SM = ctx.SourceMgr;
|
||||||
|
|
||||||
auto *staticStringDecl = ctx.getStaticStringDecl();
|
auto *staticStringDecl = ctx.getStaticStringDecl();
|
||||||
auto staticStringType = staticStringDecl->getDeclaredInterfaceType();
|
auto staticStringType = staticStringDecl->getDeclaredInterfaceType();
|
||||||
@@ -574,8 +576,9 @@ synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *) {
|
|||||||
auto uintInit = ctx.getIntBuiltinInitDecl(uintDecl);
|
auto uintInit = ctx.getIntBuiltinInitDecl(uintDecl);
|
||||||
|
|
||||||
auto missingTransportDecl = ctx.getMissingDistributedActorTransport();
|
auto missingTransportDecl = ctx.getMissingDistributedActorTransport();
|
||||||
|
assert(missingTransportDecl);
|
||||||
|
|
||||||
// Create a call to Swift._missingDistributedActorTransport // TODO: move to `Distributed` module
|
// Create a call to _Distributed._missingDistributedActorTransport
|
||||||
auto loc = func->getLoc();
|
auto loc = func->getLoc();
|
||||||
Expr *ref = new (ctx) DeclRefExpr(missingTransportDecl,
|
Expr *ref = new (ctx) DeclRefExpr(missingTransportDecl,
|
||||||
DeclNameLoc(loc), /*Implicit=*/true);
|
DeclNameLoc(loc), /*Implicit=*/true);
|
||||||
@@ -594,23 +597,34 @@ synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *) {
|
|||||||
assert(isa<ConstructorDecl>(className->getBuiltinInitializer().getDecl()));
|
assert(isa<ConstructorDecl>(className->getBuiltinInitializer().getDecl()));
|
||||||
className->setType(staticStringType);
|
className->setType(staticStringType);
|
||||||
|
|
||||||
auto *funcName = new (ctx) MagicIdentifierLiteralExpr(
|
auto *funcName = new (ctx) StringLiteralExpr(
|
||||||
MagicIdentifierLiteralExpr::Function, loc, /*Implicit=*/true);
|
ctx.AllocateCopy(func->getName().getBaseName().getIdentifier().str()), loc,
|
||||||
|
/*Implicit=*/true);
|
||||||
funcName->setType(staticStringType);
|
funcName->setType(staticStringType);
|
||||||
funcName->setBuiltinInitializer(staticStringInit);
|
funcName->setBuiltinInitializer(staticStringInit);
|
||||||
|
|
||||||
auto *file = new (ctx) MagicIdentifierLiteralExpr(
|
// Note: Sadly we cannot just rely on #function, #file, #line for the location
|
||||||
MagicIdentifierLiteralExpr::FileID, loc, /*Implicit=*/true);
|
// (MagicIdentifierLiteralExpr), of the call because the call is made from a thunk.
|
||||||
|
// That thunk does not carry those info today although it could.
|
||||||
|
//
|
||||||
|
// Instead, we offer the location where the distributed func was declared.
|
||||||
|
auto fileString = SM.getDisplayNameForLoc(distributedFunc->getStartLoc());
|
||||||
|
auto *file = new (ctx) StringLiteralExpr(fileString, loc, /*Implicit=*/true);
|
||||||
file->setType(staticStringType);
|
file->setType(staticStringType);
|
||||||
file->setBuiltinInitializer(staticStringInit);
|
file->setBuiltinInitializer(staticStringInit);
|
||||||
|
|
||||||
auto *line = new (ctx) MagicIdentifierLiteralExpr(
|
auto startLineAndCol = SM.getPresumedLineAndColumnForLoc(distributedFunc->getStartLoc());
|
||||||
MagicIdentifierLiteralExpr::Line, loc, /*Implicit=*/true);
|
// auto *line = new (ctx) MagicIdentifierLiteralExpr(
|
||||||
|
// MagicIdentifierLiteralExpr::Line, loc, /*Implicit=*/true);
|
||||||
|
// auto *line = new (ctx) IntegerLiteralExpr(startLineAndCol.first, loc,
|
||||||
|
// /*implicit*/ true);
|
||||||
|
auto *line = IntegerLiteralExpr::createFromUnsigned(ctx, startLineAndCol.first);
|
||||||
line->setType(uintType);
|
line->setType(uintType);
|
||||||
line->setBuiltinInitializer(uintInit);
|
line->setBuiltinInitializer(uintInit);
|
||||||
|
|
||||||
auto *column = new (ctx) MagicIdentifierLiteralExpr(
|
// auto *column = new (ctx) MagicIdentifierLiteralExpr(
|
||||||
MagicIdentifierLiteralExpr::Column, loc, /*Implicit=*/true);
|
// MagicIdentifierLiteralExpr::Column, loc, /*Implicit=*/true);
|
||||||
|
auto *column = IntegerLiteralExpr::createFromUnsigned(ctx, startLineAndCol.second);
|
||||||
column->setType(uintType);
|
column->setType(uintType);
|
||||||
column->setBuiltinInitializer(uintInit);
|
column->setBuiltinInitializer(uintInit);
|
||||||
|
|
||||||
@@ -624,9 +638,6 @@ synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *) {
|
|||||||
// stmts.push_back(new (ctx) ReturnStmt(SourceLoc(), /*Result=*/nullptr)); // FIXME: this causes 'different types for return type: String vs. ()'
|
// stmts.push_back(new (ctx) ReturnStmt(SourceLoc(), /*Result=*/nullptr)); // FIXME: this causes 'different types for return type: String vs. ()'
|
||||||
auto body = BraceStmt::create(ctx, SourceLoc(), stmts, SourceLoc(),
|
auto body = BraceStmt::create(ctx, SourceLoc(), stmts, SourceLoc(),
|
||||||
/*implicit=*/true);
|
/*implicit=*/true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return { body, /*isTypeChecked=*/true };
|
return { body, /*isTypeChecked=*/true };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,7 +691,7 @@ static void addImplicitRemoteActorFunction(ClassDecl *decl, FuncDecl *func) {
|
|||||||
remoteFuncDecl->setUserAccessible(false);
|
remoteFuncDecl->setUserAccessible(false);
|
||||||
remoteFuncDecl->setSynthesized();
|
remoteFuncDecl->setSynthesized();
|
||||||
|
|
||||||
remoteFuncDecl->setBodySynthesizer(&synthesizeRemoteFuncStubBody);
|
remoteFuncDecl->setBodySynthesizer(&synthesizeRemoteFuncStubBody, func);
|
||||||
|
|
||||||
// same access control as the original function is fine
|
// same access control as the original function is fine
|
||||||
remoteFuncDecl->copyFormalAccessFrom(func, /*sourceIsParentContext=*/false);
|
remoteFuncDecl->copyFormalAccessFrom(func, /*sourceIsParentContext=*/false);
|
||||||
|
|||||||
@@ -11,260 +11,23 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
import Swift
|
import Swift
|
||||||
import _Concurrency
|
|
||||||
|
|
||||||
/// Common protocol to which all distributed actors conform implicitly.
|
/// Report a call to a _remote function on a distributed (remote) actor,
|
||||||
///
|
/// that was not dynamically replaced by some specific ActorTransport library.
|
||||||
/// It is not possible to conform to this protocol manually explicitly.
|
@_transparent
|
||||||
/// Only a 'distributed actor' declaration or protocol with 'DistributedActor'
|
public func _missingDistributedActorTransport(
|
||||||
/// requirement may conform to this protocol.
|
className: StaticString, functionName: StaticString,
|
||||||
///
|
file: StaticString, line: UInt, column: UInt
|
||||||
/// The 'DistributedActor' protocol provides the core functionality of any
|
) -> Never {
|
||||||
/// distributed actor, which involves transforming actor
|
// This function is marked @_transparent so that it is inlined into the caller
|
||||||
/// which involves enqueuing new partial tasks to be executed at some
|
// (the remote function stub), and, depending on the build configuration,
|
||||||
/// point.
|
// redundant parameter values (#file etc.) are eliminated, and don't leak
|
||||||
@available(SwiftStdlib 5.5, *)
|
// information about the user's source.
|
||||||
public protocol DistributedActor: Actor, Codable {
|
fatalError(
|
||||||
|
"""
|
||||||
/// Creates new (local) distributed actor instance, bound to the passed transport.
|
Invoked remote placeholder function '\(functionName)' on remote \
|
||||||
///
|
distributed actor of type '\(className)'. Configure an appropriate \
|
||||||
/// Upon initialization, the `actorAddress` field is populated by the transport,
|
'ActorTransport' for this actor to resolve this error (e.g. by depending \
|
||||||
/// with an address assigned to this actor.
|
on some specific transport library).
|
||||||
///
|
""", file: file, line: line)
|
||||||
/// - Parameter transport: the transport this distributed actor instance will
|
}
|
||||||
/// associated with.
|
|
||||||
init(transport: ActorTransport)
|
|
||||||
|
|
||||||
/// Resolves the passed in `address` against the `transport`,
|
|
||||||
/// returning either a local or remote actor reference.
|
|
||||||
///
|
|
||||||
/// The transport will be asked to `resolve` the address and return either
|
|
||||||
/// a local instance or determine that a proxy instance should be created
|
|
||||||
/// for this address. A proxy actor will forward all invocations through
|
|
||||||
/// the transport, allowing it to take over the remote messaging with the
|
|
||||||
/// remote actor instance.
|
|
||||||
///
|
|
||||||
/// - Parameter address: the address to resolve, and produce an instance or proxy for.
|
|
||||||
/// - Parameter transport: transport which should be used to resolve the `address`.
|
|
||||||
init(resolve address: ActorAddress, using transport: ActorTransport) throws
|
|
||||||
|
|
||||||
/// The `ActorTransport` associated with this actor.
|
|
||||||
/// It is immutable and equal to the transport passed in the local/resolve
|
|
||||||
/// initializer.
|
|
||||||
///
|
|
||||||
/// Conformance to this requirement is synthesized automatically for any
|
|
||||||
/// `distributed actor` declaration.
|
|
||||||
nonisolated var actorTransport: ActorTransport { get }
|
|
||||||
|
|
||||||
/// Logical address which this distributed actor represents.
|
|
||||||
///
|
|
||||||
/// An address is always uniquely pointing at a specific actor instance.
|
|
||||||
///
|
|
||||||
/// Conformance to this requirement is synthesized automatically for any
|
|
||||||
/// `distributed actor` declaration.
|
|
||||||
nonisolated var actorAddress: ActorAddress { get }
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==== Codable conformance ----------------------------------------------------
|
|
||||||
|
|
||||||
extension CodingUserInfoKey {
|
|
||||||
@available(SwiftStdlib 5.5, *)
|
|
||||||
static let actorTransportKey = CodingUserInfoKey(rawValue: "$dist_act_trans")!
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(SwiftStdlib 5.5, *)
|
|
||||||
extension DistributedActor {
|
|
||||||
nonisolated public init(from decoder: Decoder) throws {
|
|
||||||
// guard let transport = decoder.userInfo[.actorTransportKey] as? ActorTransport else {
|
|
||||||
// throw DistributedActorCodingError(message:
|
|
||||||
// "ActorTransport not available under the decoder.userInfo")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var container = try decoder.singleValueContainer()
|
|
||||||
// let address = try container.decode(ActorAddress.self)
|
|
||||||
// self = try Self(resolve: address, using: transport) // FIXME: This is going to be solved by the init() work!!!!
|
|
||||||
fatalError("\(#function) is not implemented yet for distributed actors'")
|
|
||||||
}
|
|
||||||
|
|
||||||
nonisolated public func encode(to encoder: Encoder) throws {
|
|
||||||
var container = encoder.singleValueContainer()
|
|
||||||
try container.encode(self.actorAddress)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/******************************************************************************/
|
|
||||||
/***************************** Actor Transport ********************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
@available(SwiftStdlib 5.5, *)
|
|
||||||
public protocol ActorTransport: Sendable {
|
|
||||||
/// Resolve a local or remote actor address to a real actor instance, or throw if unable to.
|
|
||||||
/// The returned value is either a local actor or proxy to a remote actor.
|
|
||||||
func resolve<Act>(address: ActorAddress, as actorType: Act.Type)
|
|
||||||
throws -> ActorResolved<Act> where Act: DistributedActor
|
|
||||||
|
|
||||||
/// Create an `ActorAddress` for the passed actor type.
|
|
||||||
///
|
|
||||||
/// This function is invoked by an distributed actor during its initialization,
|
|
||||||
/// and the returned address value is stored along with it for the time of its
|
|
||||||
/// lifetime.
|
|
||||||
///
|
|
||||||
/// The address MUST uniquely identify the actor, and allow resolving it.
|
|
||||||
/// E.g. if an actor is created under address `addr1` then immediately invoking
|
|
||||||
/// `transport.resolve(address: addr1, as: Greeter.self)` MUST return a reference
|
|
||||||
/// to the same actor.
|
|
||||||
func assignAddress<Act>(
|
|
||||||
_ actorType: Act.Type
|
|
||||||
) -> ActorAddress
|
|
||||||
where Act: DistributedActor
|
|
||||||
|
|
||||||
func actorReady<Act>(
|
|
||||||
_ actor: Act
|
|
||||||
) where Act: DistributedActor
|
|
||||||
|
|
||||||
/// Called during actor deinit/destroy.
|
|
||||||
func resignAddress(
|
|
||||||
_ address: ActorAddress
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(SwiftStdlib 5.5, *)
|
|
||||||
public enum ActorResolved<Act: DistributedActor> {
|
|
||||||
case resolved(Act)
|
|
||||||
case makeProxy
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/***************************** Actor Address **********************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
/// Uniquely identifies a distributed actor, and enables sending messages even to remote actors.
|
|
||||||
///
|
|
||||||
/// ## Identity
|
|
||||||
/// The address is the source of truth with regards to referring to a _specific_ actor in the system.
|
|
||||||
/// This is in contrast to an `ActorPath` which can be thought of as paths in a filesystem, however without any uniqueness
|
|
||||||
/// or identity guarantees about the files those paths point to.
|
|
||||||
///
|
|
||||||
/// ## Lifecycle
|
|
||||||
/// Note, that an ActorAddress is a pure value, and as such does not "participate" in an actors lifecycle;
|
|
||||||
/// Thus, it may represent an address of an actor that has already terminated, so attempts to locate (resolve)
|
|
||||||
/// an `ActorRef` for this address may result with a reference to dead letters (meaning, that the actor this address
|
|
||||||
/// had pointed to does not exist, and most likely is dead / terminated).
|
|
||||||
///
|
|
||||||
/// ## Serialization
|
|
||||||
///
|
|
||||||
/// An address can be serialized using `Codable` or other serialization mechanisms.
|
|
||||||
/// When shared over the network or with other processes it must include the origin's
|
|
||||||
/// system address (e.g. the network address of the host, or process identifier).
|
|
||||||
///
|
|
||||||
/// When using `Codable` serialization this is done automatically, by looking up
|
|
||||||
/// the address of the `ActorTransport` the actor is associated with if was a local
|
|
||||||
/// instance, or simply carrying the full address if it already was a remote reference.
|
|
||||||
///
|
|
||||||
/// ## Format
|
|
||||||
/// The address consists of the following parts:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// | node | path | incarnation |
|
|
||||||
/// ( protocol | name? | host | port ) ( [segments] name )? ( uint32 )
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// For example: `sact://human-readable-name@127.0.0.1:7337/user/wallet/id-121242`.
|
|
||||||
/// Note that the `ActorIncarnation` is not printed by default in the String representation of a path, yet may be inspected on demand.
|
|
||||||
@available(SwiftStdlib 5.5, *)
|
|
||||||
public struct ActorAddress: Codable, Sendable, Equatable, Hashable {
|
|
||||||
/// Uniquely specifies the actor transport and the protocol used by it.
|
|
||||||
///
|
|
||||||
/// E.g. "xpc", "specific-clustering-protocol" etc.
|
|
||||||
public var `protocol`: String
|
|
||||||
|
|
||||||
public var host: String?
|
|
||||||
public var port: Int?
|
|
||||||
public var nodeID: UInt64?
|
|
||||||
public var path: String?
|
|
||||||
|
|
||||||
/// Unique Identifier of this actor.
|
|
||||||
public var uid: UInt64 // TODO: should we remove this
|
|
||||||
|
|
||||||
// FIXME: remove this or implement for real; this is just a hack implementation for now
|
|
||||||
public init(parse: String) {
|
|
||||||
self.protocol = "sact"
|
|
||||||
self.host = "xxx"
|
|
||||||
self.port = 7337
|
|
||||||
self.nodeID = 11
|
|
||||||
self.path = "example"
|
|
||||||
self.uid = 123123
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: naive impl, bring in a real one
|
|
||||||
@available(SwiftStdlib 5.5, *)
|
|
||||||
extension ActorAddress: CustomStringConvertible {
|
|
||||||
public var description: String {
|
|
||||||
var result = `protocol`
|
|
||||||
result += "://"
|
|
||||||
if let host = host {
|
|
||||||
result += host
|
|
||||||
}
|
|
||||||
if let port = port {
|
|
||||||
result += ":\(port)"
|
|
||||||
}
|
|
||||||
// TODO: decide if we'd want to print the nodeID too here.
|
|
||||||
if let path = path {
|
|
||||||
result += "/\(path)"
|
|
||||||
}
|
|
||||||
if uid > 0 {
|
|
||||||
result += "#\(uid)"
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************** Misc ****************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
/// Error protocol to which errors thrown by any `ActorTransport` should conform.
|
|
||||||
@available(SwiftStdlib 5.5, *)
|
|
||||||
public protocol ActorTransportError: Error {}
|
|
||||||
|
|
||||||
@available(SwiftStdlib 5.5, *)
|
|
||||||
public struct DistributedActorCodingError: ActorTransportError {
|
|
||||||
public let message: String
|
|
||||||
|
|
||||||
public init(message: String) {
|
|
||||||
self.message = message
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func missingTransportUserInfo<Act>(_ actorType: Act.Type) -> Self
|
|
||||||
where Act: DistributedActor {
|
|
||||||
.init(message: "Missing ActorTransport userInfo while decoding")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/************************* Runtime Functions **********************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// ==== isRemote / isLocal -----------------------------------------------------
|
|
||||||
|
|
||||||
@_silgen_name("swift_distributed_actor_is_remote")
|
|
||||||
func __isRemoteActor(_ actor: AnyObject) -> Bool
|
|
||||||
|
|
||||||
func __isLocalActor(_ actor: AnyObject) -> Bool {
|
|
||||||
return !__isRemoteActor(actor)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==== Proxy Actor lifecycle --------------------------------------------------
|
|
||||||
|
|
||||||
/// Called to initialize the distributed-remote actor 'proxy' instance in an actor.
|
|
||||||
/// The implementation will call this within the actor's initializer.
|
|
||||||
@_silgen_name("swift_distributedActor_remote_initialize")
|
|
||||||
func _distributedActorRemoteInitialize(_ actor: AnyObject)
|
|
||||||
|
|
||||||
/// Called to destroy the default actor instance in an actor.
|
|
||||||
/// The implementation will call this within the actor's deinit.
|
|
||||||
///
|
|
||||||
/// This will call `actorTransport.resignAddress(self.actorAddress)`.
|
|
||||||
@_silgen_name("swift_distributedActor_destroy")
|
|
||||||
func _distributedActorDestroy(_ actor: AnyObject)
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by Konrad Malawski on 2021/06/07.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef SWIFT_ASSERTIONREPORTINGDISTRIBUTED_H
|
|
||||||
#define SWIFT_ASSERTIONREPORTINGDISTRIBUTED_H
|
|
||||||
|
|
||||||
#endif //SWIFT_ASSERTIONREPORTINGDISTRIBUTED_H
|
|
||||||
@@ -14,6 +14,7 @@ set(swift_distributed_link_libraries
|
|||||||
swiftCore)
|
swiftCore)
|
||||||
|
|
||||||
add_swift_target_library(swift_Distributed ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
|
add_swift_target_library(swift_Distributed ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
|
||||||
|
AssertDistributed.swift
|
||||||
DistributedActor.swift
|
DistributedActor.swift
|
||||||
|
|
||||||
SWIFT_MODULE_DEPENDS_LINUX Glibc
|
SWIFT_MODULE_DEPENDS_LINUX Glibc
|
||||||
|
|||||||
@@ -68,21 +68,6 @@ void _swift_stdlib_reportUnimplementedInitializer(
|
|||||||
const unsigned char *initName, int initNameLength,
|
const unsigned char *initName, int initNameLength,
|
||||||
__swift_uint32_t flags);
|
__swift_uint32_t flags);
|
||||||
|
|
||||||
/// Report a call to a _remote function on a distributed (remote) actor,
|
|
||||||
/// that was not dynamically replaced by some specific ActorTransport library.
|
|
||||||
///
|
|
||||||
/// <file>: <line>: <column>: Fatal error: remote function 'greet(name:)'
|
|
||||||
/// invoked on remote distributed actor reference of type 'Greeter'.
|
|
||||||
/// Configure an appropriate 'ActorTransport' for this actor to resolve
|
|
||||||
/// this error (e.g. by depending on some specific ActorTransport library)
|
|
||||||
SWIFT_RUNTIME_STDLIB_API
|
|
||||||
void _swift_stdlib_reportMissingDistributedActorTransport(
|
|
||||||
const unsigned char *className, int classNameLength,
|
|
||||||
const unsigned char *funcName, int funcNameLength,
|
|
||||||
const unsigned char *file, int fileLength,
|
|
||||||
__swift_uint32_t line, __swift_uint32_t column,
|
|
||||||
__swift_uint32_t flags);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -222,36 +222,6 @@ func _unimplementedInitializer(className: StaticString,
|
|||||||
Builtin.int_trap()
|
Builtin.int_trap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a fatal error message when a distributed remote actor function is invoked
|
|
||||||
/// without a transport having dynamically replaced its _remote_ function implementation.
|
|
||||||
@_transparent
|
|
||||||
public // COMPILER_INTRINSIC
|
|
||||||
func _missingDistributedActorTransport(className: StaticString,
|
|
||||||
functionName: StaticString = #function,
|
|
||||||
file: StaticString = #file,
|
|
||||||
line: UInt = #line,
|
|
||||||
column: UInt = #column
|
|
||||||
) -> Never {
|
|
||||||
// This function is marked @_transparent so that it is inlined into the caller
|
|
||||||
// (the initializer stub), and, depending on the build configuration,
|
|
||||||
// redundant parameter values (#file etc.) are eliminated, and don't leak
|
|
||||||
// information about the user's source.
|
|
||||||
className.withUTF8Buffer { className in
|
|
||||||
functionName.withUTF8Buffer { functionName in
|
|
||||||
file.withUTF8Buffer { file in
|
|
||||||
_swift_stdlib_reportMissingDistributedActorTransport(
|
|
||||||
className.baseAddress!, CInt(className.count),
|
|
||||||
functionName.baseAddress!, CInt(functionName.count),
|
|
||||||
file.baseAddress!, CInt(file.count),
|
|
||||||
UInt32(line), UInt32(column),
|
|
||||||
/*flags:*/ 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Builtin.int_trap()
|
|
||||||
}
|
|
||||||
|
|
||||||
public // COMPILER_INTRINSIC
|
public // COMPILER_INTRINSIC
|
||||||
func _undefined<T>(
|
func _undefined<T>(
|
||||||
_ message: @autoclosure () -> String = String(),
|
_ message: @autoclosure () -> String = String(),
|
||||||
|
|||||||
@@ -117,25 +117,3 @@ void _swift_stdlib_reportUnimplementedInitializer(
|
|||||||
free(log);
|
free(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _swift_stdlib_reportMissingDistributedActorTransport(
|
|
||||||
const unsigned char *className, int classNameLength,
|
|
||||||
const unsigned char *funcName, int funcNameLength,
|
|
||||||
const unsigned char *file, int fileLength,
|
|
||||||
uint32_t line, uint32_t column,
|
|
||||||
uint32_t flags
|
|
||||||
) {
|
|
||||||
char *log;
|
|
||||||
swift_asprintf(
|
|
||||||
&log,
|
|
||||||
"%.*s:%" PRIu32 ": Fatal error: remote function '%.*s' invoked on remote "
|
|
||||||
"distributed actor reference of type '%.*s'. Configure an appropriate "
|
|
||||||
"'ActorTransport' for this actor to resolve this error (e.g. by depending "
|
|
||||||
"on some specific ActorTransport library)\n",
|
|
||||||
fileLength, file,
|
|
||||||
line,
|
|
||||||
funcNameLength, funcName,
|
|
||||||
classNameLength, className);
|
|
||||||
|
|
||||||
swift_reportError(flags, log);
|
|
||||||
free(log);
|
|
||||||
}
|
|
||||||
|
|||||||
63
test/Distributed/Runtime/distributed_no_transport_boom.swift
Normal file
63
test/Distributed/Runtime/distributed_no_transport_boom.swift
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// RUN: %target-fail-simple-swift(-Xfrontend -enable-experimental-distributed -parse-as-library %import-libdispatch) 2>&1 | %FileCheck %s
|
||||||
|
//
|
||||||
|
// // TODO: could not figure out how to use 'not --crash' it never is used with target-run-simple-swift
|
||||||
|
// This test is intended to *crash*, so we're using target-fail-simple-swift
|
||||||
|
// which expects the exit code of the program to be non-zero;
|
||||||
|
// We then check stderr for the expected error message using filecheck as usual.
|
||||||
|
|
||||||
|
// REQUIRES: executable_test
|
||||||
|
// REQUIRES: concurrency
|
||||||
|
// REQUIRES: distributed
|
||||||
|
|
||||||
|
import _Distributed
|
||||||
|
|
||||||
|
@available(SwiftStdlib 5.5, *)
|
||||||
|
distributed actor SomeSpecificDistributedActor {
|
||||||
|
distributed func hello() async throws -> String {
|
||||||
|
"local impl"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Fake Transport ---------------------------------------------------------
|
||||||
|
|
||||||
|
@available(SwiftStdlib 5.5, *)
|
||||||
|
struct FakeTransport: ActorTransport {
|
||||||
|
func resolve<Act>(address: ActorAddress, as actorType: Act.Type)
|
||||||
|
throws -> ActorResolved<Act> where Act: DistributedActor {
|
||||||
|
return .makeProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func assignAddress<Act>(
|
||||||
|
_ actorType: Act.Type
|
||||||
|
) -> ActorAddress where Act : DistributedActor {
|
||||||
|
ActorAddress(parse: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
public func actorReady<Act>(
|
||||||
|
_ actor: Act
|
||||||
|
) where Act: DistributedActor {}
|
||||||
|
|
||||||
|
public func resignAddress(
|
||||||
|
_ address: ActorAddress
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Execute ----------------------------------------------------------------
|
||||||
|
|
||||||
|
@available(SwiftStdlib 5.5, *)
|
||||||
|
func test_remote() async {
|
||||||
|
let address = ActorAddress(parse: "")
|
||||||
|
let transport = FakeTransport()
|
||||||
|
|
||||||
|
let remote = try! SomeSpecificDistributedActor(resolve: address, using: transport)
|
||||||
|
_ = try! await remote.hello() // let it crash!
|
||||||
|
// CHECK: SOURCE_DIR/test/Distributed/Runtime/distributed_no_transport_boom.swift:16: Fatal error: Invoked remote placeholder function '_remote_hello' on remote distributed actor of type 'main.SomeSpecificDistributedActor'. Configure an appropriate 'ActorTransport' for this actor to resolve this error (e.g. by depending on some specific transport library).
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(SwiftStdlib 5.5, *)
|
||||||
|
@main struct Main {
|
||||||
|
static func main() async {
|
||||||
|
await test_remote()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user