Skip to content

Commit bb9f2e4

Browse files
committed
[Distributed] move _missingDistributedActorTransport to _Distributed
1 parent 20382d5 commit bb9f2e4

File tree

10 files changed

+109
-349
lines changed

10 files changed

+109
-349
lines changed

include/swift/AST/KnownDecls.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,4 @@ FUNC_DECL(Swap, "swap")
8888
FUNC_DECL(UnimplementedInitializer, "_unimplementedInitializer")
8989
FUNC_DECL(Undefined, "_undefined")
9090

91-
// TODO: move to _Distributed
92-
FUNC_DECL(MissingDistributedActorTransport, "_missingDistributedActorTransport")
93-
9491
#undef FUNC_DECL

include/swift/AST/KnownSDKDecls.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
# define KNOWN_SDK_FUNC_DECL(Module, Name, Id)
2020
#endif
2121

22-
//KNOWN_SDK_FUNC_DECL(Distributed, MissingDistributedActorTransport, "_missingDistributedActorTransport")
22+
KNOWN_SDK_FUNC_DECL(Distributed, MissingDistributedActorTransport, "_missingDistributedActorTransport")
2323
KNOWN_SDK_FUNC_DECL(Distributed, IsRemoteDistributedActor, "__isRemoteActor")
2424

2525
#undef KNOWN_SDK_FUNC_DECL

lib/Sema/CodeSynthesisDistributedActor.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -561,9 +561,11 @@ static void addImplicitDistributedActorStoredProperties(ClassDecl *decl) {
561561
///
562562
/// Create a stub body that emits a fatal error message.
563563
static std::pair<BraceStmt *, bool>
564-
synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *) {
564+
synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *context) {
565+
auto distributedFunc = static_cast<AbstractFunctionDecl *>(context);
565566
auto classDecl = func->getDeclContext()->getSelfClassDecl();
566567
auto &ctx = func->getASTContext();
568+
auto &SM = ctx.SourceMgr;
567569

568570
auto *staticStringDecl = ctx.getStaticStringDecl();
569571
auto staticStringType = staticStringDecl->getDeclaredInterfaceType();
@@ -574,8 +576,9 @@ synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *) {
574576
auto uintInit = ctx.getIntBuiltinInitDecl(uintDecl);
575577

576578
auto missingTransportDecl = ctx.getMissingDistributedActorTransport();
579+
assert(missingTransportDecl);
577580

578-
// Create a call to Swift._missingDistributedActorTransport // TODO: move to `Distributed` module
581+
// Create a call to _Distributed._missingDistributedActorTransport
579582
auto loc = func->getLoc();
580583
Expr *ref = new (ctx) DeclRefExpr(missingTransportDecl,
581584
DeclNameLoc(loc), /*Implicit=*/true);
@@ -594,23 +597,34 @@ synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *) {
594597
assert(isa<ConstructorDecl>(className->getBuiltinInitializer().getDecl()));
595598
className->setType(staticStringType);
596599

597-
auto *funcName = new (ctx) MagicIdentifierLiteralExpr(
598-
MagicIdentifierLiteralExpr::Function, loc, /*Implicit=*/true);
600+
auto *funcName = new (ctx) StringLiteralExpr(
601+
ctx.AllocateCopy(func->getName().getBaseName().getIdentifier().str()), loc,
602+
/*Implicit=*/true);
599603
funcName->setType(staticStringType);
600604
funcName->setBuiltinInitializer(staticStringInit);
601605

602-
auto *file = new (ctx) MagicIdentifierLiteralExpr(
603-
MagicIdentifierLiteralExpr::FileID, loc, /*Implicit=*/true);
606+
// Note: Sadly we cannot just rely on #function, #file, #line for the location
607+
// (MagicIdentifierLiteralExpr), of the call because the call is made from a thunk.
608+
// That thunk does not carry those info today although it could.
609+
//
610+
// Instead, we offer the location where the distributed func was declared.
611+
auto fileString = SM.getDisplayNameForLoc(distributedFunc->getStartLoc());
612+
auto *file = new (ctx) StringLiteralExpr(fileString, loc, /*Implicit=*/true);
604613
file->setType(staticStringType);
605614
file->setBuiltinInitializer(staticStringInit);
606615

607-
auto *line = new (ctx) MagicIdentifierLiteralExpr(
608-
MagicIdentifierLiteralExpr::Line, loc, /*Implicit=*/true);
616+
auto startLineAndCol = SM.getPresumedLineAndColumnForLoc(distributedFunc->getStartLoc());
617+
// auto *line = new (ctx) MagicIdentifierLiteralExpr(
618+
// MagicIdentifierLiteralExpr::Line, loc, /*Implicit=*/true);
619+
// auto *line = new (ctx) IntegerLiteralExpr(startLineAndCol.first, loc,
620+
// /*implicit*/ true);
621+
auto *line = IntegerLiteralExpr::createFromUnsigned(ctx, startLineAndCol.first);
609622
line->setType(uintType);
610623
line->setBuiltinInitializer(uintInit);
611624

612-
auto *column = new (ctx) MagicIdentifierLiteralExpr(
613-
MagicIdentifierLiteralExpr::Column, loc, /*Implicit=*/true);
625+
// auto *column = new (ctx) MagicIdentifierLiteralExpr(
626+
// MagicIdentifierLiteralExpr::Column, loc, /*Implicit=*/true);
627+
auto *column = IntegerLiteralExpr::createFromUnsigned(ctx, startLineAndCol.second);
614628
column->setType(uintType);
615629
column->setBuiltinInitializer(uintInit);
616630

@@ -624,9 +638,6 @@ synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *) {
624638
// stmts.push_back(new (ctx) ReturnStmt(SourceLoc(), /*Result=*/nullptr)); // FIXME: this causes 'different types for return type: String vs. ()'
625639
auto body = BraceStmt::create(ctx, SourceLoc(), stmts, SourceLoc(),
626640
/*implicit=*/true);
627-
628-
629-
630641
return { body, /*isTypeChecked=*/true };
631642
}
632643

@@ -680,7 +691,7 @@ static void addImplicitRemoteActorFunction(ClassDecl *decl, FuncDecl *func) {
680691
remoteFuncDecl->setUserAccessible(false);
681692
remoteFuncDecl->setSynthesized();
682693

683-
remoteFuncDecl->setBodySynthesizer(&synthesizeRemoteFuncStubBody);
694+
remoteFuncDecl->setBodySynthesizer(&synthesizeRemoteFuncStubBody, func);
684695

685696
// same access control as the original function is fine
686697
remoteFuncDecl->copyFormalAccessFrom(func, /*sourceIsParentContext=*/false);

stdlib/public/Distributed/AssertDistributed.swift

Lines changed: 19 additions & 256 deletions
Original file line numberDiff line numberDiff line change
@@ -11,260 +11,23 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Swift
14-
import _Concurrency
1514

16-
/// Common protocol to which all distributed actors conform implicitly.
17-
///
18-
/// It is not possible to conform to this protocol manually explicitly.
19-
/// Only a 'distributed actor' declaration or protocol with 'DistributedActor'
20-
/// requirement may conform to this protocol.
21-
///
22-
/// The 'DistributedActor' protocol provides the core functionality of any
23-
/// distributed actor, which involves transforming actor
24-
/// which involves enqueuing new partial tasks to be executed at some
25-
/// point.
26-
@available(SwiftStdlib 5.5, *)
27-
public protocol DistributedActor: Actor, Codable {
28-
29-
/// Creates new (local) distributed actor instance, bound to the passed transport.
30-
///
31-
/// Upon initialization, the `actorAddress` field is populated by the transport,
32-
/// with an address assigned to this actor.
33-
///
34-
/// - Parameter transport: the transport this distributed actor instance will
35-
/// associated with.
36-
init(transport: ActorTransport)
37-
38-
/// Resolves the passed in `address` against the `transport`,
39-
/// returning either a local or remote actor reference.
40-
///
41-
/// The transport will be asked to `resolve` the address and return either
42-
/// a local instance or determine that a proxy instance should be created
43-
/// for this address. A proxy actor will forward all invocations through
44-
/// the transport, allowing it to take over the remote messaging with the
45-
/// remote actor instance.
46-
///
47-
/// - Parameter address: the address to resolve, and produce an instance or proxy for.
48-
/// - Parameter transport: transport which should be used to resolve the `address`.
49-
init(resolve address: ActorAddress, using transport: ActorTransport) throws
50-
51-
/// The `ActorTransport` associated with this actor.
52-
/// It is immutable and equal to the transport passed in the local/resolve
53-
/// initializer.
54-
///
55-
/// Conformance to this requirement is synthesized automatically for any
56-
/// `distributed actor` declaration.
57-
nonisolated var actorTransport: ActorTransport { get }
58-
59-
/// Logical address which this distributed actor represents.
60-
///
61-
/// An address is always uniquely pointing at a specific actor instance.
62-
///
63-
/// Conformance to this requirement is synthesized automatically for any
64-
/// `distributed actor` declaration.
65-
nonisolated var actorAddress: ActorAddress { get }
66-
}
67-
68-
// ==== Codable conformance ----------------------------------------------------
69-
70-
extension CodingUserInfoKey {
71-
@available(SwiftStdlib 5.5, *)
72-
static let actorTransportKey = CodingUserInfoKey(rawValue: "$dist_act_trans")!
73-
}
74-
75-
@available(SwiftStdlib 5.5, *)
76-
extension DistributedActor {
77-
nonisolated public init(from decoder: Decoder) throws {
78-
// guard let transport = decoder.userInfo[.actorTransportKey] as? ActorTransport else {
79-
// throw DistributedActorCodingError(message:
80-
// "ActorTransport not available under the decoder.userInfo")
81-
// }
82-
//
83-
// var container = try decoder.singleValueContainer()
84-
// let address = try container.decode(ActorAddress.self)
85-
// self = try Self(resolve: address, using: transport) // FIXME: This is going to be solved by the init() work!!!!
86-
fatalError("\(#function) is not implemented yet for distributed actors'")
87-
}
88-
89-
nonisolated public func encode(to encoder: Encoder) throws {
90-
var container = encoder.singleValueContainer()
91-
try container.encode(self.actorAddress)
92-
}
93-
}
94-
/******************************************************************************/
95-
/***************************** Actor Transport ********************************/
96-
/******************************************************************************/
97-
98-
@available(SwiftStdlib 5.5, *)
99-
public protocol ActorTransport: Sendable {
100-
/// Resolve a local or remote actor address to a real actor instance, or throw if unable to.
101-
/// The returned value is either a local actor or proxy to a remote actor.
102-
func resolve<Act>(address: ActorAddress, as actorType: Act.Type)
103-
throws -> ActorResolved<Act> where Act: DistributedActor
104-
105-
/// Create an `ActorAddress` for the passed actor type.
106-
///
107-
/// This function is invoked by an distributed actor during its initialization,
108-
/// and the returned address value is stored along with it for the time of its
109-
/// lifetime.
110-
///
111-
/// The address MUST uniquely identify the actor, and allow resolving it.
112-
/// E.g. if an actor is created under address `addr1` then immediately invoking
113-
/// `transport.resolve(address: addr1, as: Greeter.self)` MUST return a reference
114-
/// to the same actor.
115-
func assignAddress<Act>(
116-
_ actorType: Act.Type
117-
) -> ActorAddress
118-
where Act: DistributedActor
119-
120-
func actorReady<Act>(
121-
_ actor: Act
122-
) where Act: DistributedActor
123-
124-
/// Called during actor deinit/destroy.
125-
func resignAddress(
126-
_ address: ActorAddress
127-
)
128-
129-
}
130-
131-
@available(SwiftStdlib 5.5, *)
132-
public enum ActorResolved<Act: DistributedActor> {
133-
case resolved(Act)
134-
case makeProxy
135-
}
136-
137-
/******************************************************************************/
138-
/***************************** Actor Address **********************************/
139-
/******************************************************************************/
140-
141-
/// Uniquely identifies a distributed actor, and enables sending messages even to remote actors.
142-
///
143-
/// ## Identity
144-
/// The address is the source of truth with regards to referring to a _specific_ actor in the system.
145-
/// This is in contrast to an `ActorPath` which can be thought of as paths in a filesystem, however without any uniqueness
146-
/// or identity guarantees about the files those paths point to.
147-
///
148-
/// ## Lifecycle
149-
/// Note, that an ActorAddress is a pure value, and as such does not "participate" in an actors lifecycle;
150-
/// Thus, it may represent an address of an actor that has already terminated, so attempts to locate (resolve)
151-
/// an `ActorRef` for this address may result with a reference to dead letters (meaning, that the actor this address
152-
/// had pointed to does not exist, and most likely is dead / terminated).
153-
///
154-
/// ## Serialization
155-
///
156-
/// An address can be serialized using `Codable` or other serialization mechanisms.
157-
/// When shared over the network or with other processes it must include the origin's
158-
/// system address (e.g. the network address of the host, or process identifier).
159-
///
160-
/// When using `Codable` serialization this is done automatically, by looking up
161-
/// the address of the `ActorTransport` the actor is associated with if was a local
162-
/// instance, or simply carrying the full address if it already was a remote reference.
163-
///
164-
/// ## Format
165-
/// The address consists of the following parts:
166-
///
167-
/// ```
168-
/// | node | path | incarnation |
169-
/// ( protocol | name? | host | port ) ( [segments] name )? ( uint32 )
170-
/// ```
171-
///
172-
/// For example: `sact://[email protected]:7337/user/wallet/id-121242`.
173-
/// Note that the `ActorIncarnation` is not printed by default in the String representation of a path, yet may be inspected on demand.
174-
@available(SwiftStdlib 5.5, *)
175-
public struct ActorAddress: Codable, Sendable, Equatable, Hashable {
176-
/// Uniquely specifies the actor transport and the protocol used by it.
177-
///
178-
/// E.g. "xpc", "specific-clustering-protocol" etc.
179-
public var `protocol`: String
180-
181-
public var host: String?
182-
public var port: Int?
183-
public var nodeID: UInt64?
184-
public var path: String?
185-
186-
/// Unique Identifier of this actor.
187-
public var uid: UInt64 // TODO: should we remove this
188-
189-
// FIXME: remove this or implement for real; this is just a hack implementation for now
190-
public init(parse: String) {
191-
self.protocol = "sact"
192-
self.host = "xxx"
193-
self.port = 7337
194-
self.nodeID = 11
195-
self.path = "example"
196-
self.uid = 123123
197-
}
198-
}
199-
200-
// TODO: naive impl, bring in a real one
201-
@available(SwiftStdlib 5.5, *)
202-
extension ActorAddress: CustomStringConvertible {
203-
public var description: String {
204-
var result = `protocol`
205-
result += "://"
206-
if let host = host {
207-
result += host
208-
}
209-
if let port = port {
210-
result += ":\(port)"
211-
}
212-
// TODO: decide if we'd want to print the nodeID too here.
213-
if let path = path {
214-
result += "/\(path)"
215-
}
216-
if uid > 0 {
217-
result += "#\(uid)"
218-
}
219-
return result
220-
}
221-
}
222-
223-
/******************************************************************************/
224-
/******************************** Misc ****************************************/
225-
/******************************************************************************/
226-
227-
/// Error protocol to which errors thrown by any `ActorTransport` should conform.
228-
@available(SwiftStdlib 5.5, *)
229-
public protocol ActorTransportError: Error {}
230-
231-
@available(SwiftStdlib 5.5, *)
232-
public struct DistributedActorCodingError: ActorTransportError {
233-
public let message: String
234-
235-
public init(message: String) {
236-
self.message = message
237-
}
238-
239-
public static func missingTransportUserInfo<Act>(_ actorType: Act.Type) -> Self
240-
where Act: DistributedActor {
241-
.init(message: "Missing ActorTransport userInfo while decoding")
242-
}
243-
}
244-
245-
/******************************************************************************/
246-
/************************* Runtime Functions **********************************/
247-
/******************************************************************************/
248-
249-
// ==== isRemote / isLocal -----------------------------------------------------
250-
251-
@_silgen_name("swift_distributed_actor_is_remote")
252-
func __isRemoteActor(_ actor: AnyObject) -> Bool
253-
254-
func __isLocalActor(_ actor: AnyObject) -> Bool {
255-
return !__isRemoteActor(actor)
256-
}
257-
258-
// ==== Proxy Actor lifecycle --------------------------------------------------
259-
260-
/// Called to initialize the distributed-remote actor 'proxy' instance in an actor.
261-
/// The implementation will call this within the actor's initializer.
262-
@_silgen_name("swift_distributedActor_remote_initialize")
263-
func _distributedActorRemoteInitialize(_ actor: AnyObject)
264-
265-
/// Called to destroy the default actor instance in an actor.
266-
/// The implementation will call this within the actor's deinit.
267-
///
268-
/// This will call `actorTransport.resignAddress(self.actorAddress)`.
269-
@_silgen_name("swift_distributedActor_destroy")
270-
func _distributedActorDestroy(_ actor: AnyObject)
15+
/// Report a call to a _remote function on a distributed (remote) actor,
16+
/// that was not dynamically replaced by some specific ActorTransport library.
17+
@_transparent
18+
public func _missingDistributedActorTransport(
19+
className: StaticString, functionName: StaticString,
20+
file: StaticString, line: UInt, column: UInt
21+
) -> Never {
22+
// This function is marked @_transparent so that it is inlined into the caller
23+
// (the remote function stub), and, depending on the build configuration,
24+
// redundant parameter values (#file etc.) are eliminated, and don't leak
25+
// information about the user's source.
26+
fatalError(
27+
"""
28+
Invoked remote placeholder function '\(functionName)' on remote \
29+
distributed actor of type '\(className)'. Configure an appropriate \
30+
'ActorTransport' for this actor to resolve this error (e.g. by depending \
31+
on some specific transport library).
32+
""", file: file, line: line)
33+
}

stdlib/public/Distributed/AssertionReportingDistributed.h

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)