-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Distributed] Accessor must be available cross module in resilient mode #80523
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ktoso
merged 2 commits into
swiftlang:main
from
ktoso:wip-distributed-cross-module-resolvable-accessible-fun
Apr 7, 2025
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
test/Distributed/Runtime/distributed_actor_remoteCall_accessibleFunctions.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// RUN: %empty-directory(%t) | ||
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -target %target-swift-6.0-abi-triple %S/../Inputs/FakeDistributedActorSystems.swift -plugin-path %swift-plugin-dir | ||
// RUN: %target-build-swift -module-name ActorsFramework -target %target-swift-6.0-abi-triple -j2 -parse-as-library -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -plugin-path %swift-plugin-dir -o %t/a.out | ||
// RUN: %target-codesign %t/a.out | ||
// RUN: %env-SWIFT_DUMP_ACCESSIBLE_FUNCTIONS=true %target-run %t/a.out 2>&1 | %FileCheck %s --color --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: OS=windows-msvc | ||
|
||
import Distributed | ||
import FakeDistributedActorSystems | ||
|
||
// ==== Known actor system ----------------------------------------------------- | ||
|
||
public struct Response: Codable, Sendable { | ||
let resp: Int | ||
public init(resp: Int) { | ||
self.resp = resp | ||
} | ||
} | ||
|
||
public struct Provider: Codable, Sendable { | ||
let r1: Int | ||
public init(r1: Int) { | ||
self.r1 = r1 | ||
} | ||
} | ||
|
||
@Resolvable | ||
public protocol DistributedNotificationService: DistributedActor | ||
where ActorSystem == FakeRoundtripActorSystem { | ||
distributed func getArray(a1: [Int], a2: String?) async throws -> [Response] | ||
} | ||
|
||
distributed actor DistributedNotificationServiceImpl: DistributedNotificationService { | ||
typealias ActorSystem = FakeRoundtripActorSystem | ||
|
||
distributed func getArray(a1: [Int], a2: String?) async throws -> [Response] { | ||
[] // mock impl is enough | ||
} | ||
} | ||
|
||
// ==== ------------------------------------------------------------------------ | ||
|
||
@main struct Main { | ||
static func main() async throws { | ||
let roundtripSystem = FakeRoundtripActorSystem() | ||
|
||
let real: any DistributedNotificationService = DistributedNotificationServiceImpl( | ||
actorSystem: roundtripSystem) | ||
|
||
let proxy: any DistributedNotificationService = | ||
try $DistributedNotificationService.resolve(id: real.id, using: roundtripSystem) | ||
_ = try await proxy.getArray(a1: [], a2: "") | ||
|
||
// CHECK: ==== Accessible Function Records ==== | ||
|
||
// CHECK: Record name: $s15ActorsFramework30DistributedNotificationServicePAA0C001_C9ActorStubRzrlE8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTE | ||
// CHECK: Demangled: distributed thunk (extension in ActorsFramework):ActorsFramework.DistributedNotificationService< where A: Distributed._DistributedActorStub>.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<ActorsFramework.Response> | ||
// CHECK: Function Ptr: [[PTR:0x.*]] | ||
// CHECK: Flags.IsDistributed: 1 | ||
|
||
// CHECK: Record name: $s15ActorsFramework34DistributedNotificationServiceImplC8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTE | ||
// CHECK: Demangled: distributed thunk ActorsFramework.DistributedNotificationServiceImpl.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<ActorsFramework.Response> | ||
// CHECK: Function Ptr: [[PTR:0x.*]] | ||
// CHECK: Flags.IsDistributed: 1 | ||
|
||
// CHECK: Record name: $s15ActorsFramework31$DistributedNotificationServiceC8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTE | ||
// CHECK: Demangled: distributed thunk ActorsFramework.$DistributedNotificationService.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<ActorsFramework.Response> | ||
// CHECK: Function Ptr: [[PTR:0x.*]] | ||
// CHECK: Flags.IsDistributed: 1 | ||
|
||
// CHECK: Record count: 3 | ||
// CHECK: ==== End of Accessible Function Records ==== | ||
} | ||
} |
174 changes: 174 additions & 0 deletions
174
test/Distributed/Runtime/distributed_actor_remoteCall_accessibleFunctions_crossModule.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
// RUN: %empty-directory(%t/src) | ||
// RUN: split-file %s %t/src | ||
|
||
/// Build the fake actor systems lib | ||
// RUN: %target-build-swift \ | ||
// RUN: -target %target-swift-6.0-abi-triple \ | ||
// RUN: -parse-as-library -emit-library \ | ||
// RUN: -emit-module-path %t/FakeDistributedActorSystems.swiftmodule \ | ||
// RUN: -module-name FakeDistributedActorSystems \ | ||
// RUN: %S/../Inputs/FakeDistributedActorSystems.swift \ | ||
// RUN: -enable-library-evolution \ | ||
// RUN: -o %t/%target-library-name(FakeDistributedActorSystems) | ||
|
||
/// Build the Lib | ||
// RUN: %target-build-swift \ | ||
// RUN: -target %target-swift-6.0-abi-triple \ | ||
// RUN: -parse-as-library -emit-library \ | ||
// RUN: -emit-module-path %t/ResilientAPILib.swiftmodule \ | ||
// RUN: -module-name ResilientAPILib \ | ||
// RUN: -I %t \ | ||
// RUN: -L %t \ | ||
// RUN: -plugin-path %swift-plugin-dir \ | ||
// RUN: %t/src/ResilientAPILib.swift \ | ||
// RUN: -lFakeDistributedActorSystems \ | ||
// RUN: -enable-library-evolution \ | ||
// RUN: -o %t/%target-library-name(ResilientAPILib) | ||
|
||
/// Build the ActorLib | ||
// RUN: %target-build-swift \ | ||
// RUN: -target %target-swift-6.0-abi-triple \ | ||
// RUN: -parse-as-library -emit-library \ | ||
// RUN: -emit-module-path %t/ResilientImplLib.swiftmodule \ | ||
// RUN: -module-name ResilientImplLib \ | ||
// RUN: -I %t \ | ||
// RUN: -L %t \ | ||
// RUN: %t/src/ResilientImplLib.swift \ | ||
// RUN: -lFakeDistributedActorSystems \ | ||
// RUN: -lResilientAPILib \ | ||
// RUN: -enable-library-evolution \ | ||
// RUN: -o %t/%target-library-name(ResilientImplLib) | ||
|
||
/// Build the client | ||
// RUN: %target-build-swift \ | ||
// RUN: -target %target-swift-6.0-abi-triple \ | ||
// RUN: -parse-as-library \ | ||
// RUN: -lFakeDistributedActorSystems \ | ||
// RUN: -lResilientAPILib \ | ||
// RUN: -lResilientImplLib \ | ||
// RUN: -module-name main \ | ||
// RUN: -I %t \ | ||
// RUN: -L %t \ | ||
// RUN: %s \ | ||
// RUN: -enable-library-evolution \ | ||
// RUN: -o %t/a.out | ||
|
||
// Sign the main binary and all libraries | ||
// RUN: %target-codesign %t/a.out | ||
// RUN: %target-codesign %t/%target-library-name(FakeDistributedActorSystems) | ||
// RUN: %target-codesign %t/%target-library-name(ResilientAPILib) | ||
// RUN: %target-codesign %t/%target-library-name(ResilientImplLib) | ||
|
||
// Run and verify output | ||
// RUN: %env-SWIFT_DUMP_ACCESSIBLE_FUNCTIONS=true %target-run %t/a.out \ | ||
// RUN: %t/%target-library-name(FakeDistributedActorSystems) \ | ||
// RUN: %t/%target-library-name(ResilientAPILib) \ | ||
// RUN: %t/%target-library-name(ResilientImplLib) \ | ||
// RUN: 2>&1 \ | ||
// RUN: | %FileCheck %s --color --dump-input=always | ||
|
||
// REQUIRES: executable_test | ||
// REQUIRES: concurrency | ||
// REQUIRES: distributed | ||
|
||
// Locating the built libraries failed on Linux (construction of test case), | ||
// but we primarily care about macOS in this test | ||
// UNSUPPORTED: OS=linux-gnu | ||
|
||
// %env does not seem to work on Windows | ||
// UNSUPPORTED: OS=windows-msvc | ||
|
||
// UNSUPPORTED: use_os_stdlib | ||
// UNSUPPORTED: back_deployment_runtime | ||
// UNSUPPORTED: remote_run || device_run | ||
|
||
|
||
// FIXME: Also reproduces the following issue rdar://128284016 | ||
//<unknown>:0: error: symbol '$s15ResilientAPILib30ServiceProtocolP8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTj' (dispatch thunk of ResilientAPILib.ServiceProtocol.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<ResilientAPILib.Response>) is in generated IR file, but not in TBD file | ||
|
||
//<unknown>:0: error: symbol '$s15ResilientAPILib30ServiceProtocolP8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTjTu' (async function pointer to dispatch thunk of ResilientAPILib.ServiceProtocol.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<ResilientAPILib.Response>) is in generated IR file, but not in TBD file | ||
|
||
//--- ResilientAPILib.swift | ||
|
||
import Distributed | ||
import FakeDistributedActorSystems | ||
|
||
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) | ||
public struct Response: Codable {} | ||
|
||
@Resolvable | ||
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) | ||
public protocol ServiceProtocol: DistributedActor where ActorSystem == FakeRoundtripActorSystem { | ||
distributed func getArray(a1: [Int], a2: String?) -> [Response] | ||
} | ||
|
||
//--- ResilientImplLib.swift | ||
|
||
import ResilientAPILib | ||
|
||
import Distributed | ||
import FakeDistributedActorSystems | ||
|
||
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) | ||
public distributed actor ServiceImpl: ServiceProtocol { | ||
public typealias ActorSystem = FakeRoundtripActorSystem | ||
|
||
public distributed func getArray(a1: [Int], a2: String?) -> [Response] { | ||
[] | ||
} | ||
} | ||
|
||
//--- Main.swift | ||
|
||
import ResilientAPILib | ||
import ResilientImplLib | ||
|
||
import Distributed | ||
import FakeDistributedActorSystems | ||
|
||
@main | ||
struct Main { | ||
static func main() async throws { | ||
if #available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) { | ||
let system = FakeRoundtripActorSystem() | ||
|
||
let real: any ServiceProtocol = ServiceImpl(actorSystem: system) | ||
|
||
let proxy: any ServiceProtocol = | ||
try $ServiceProtocol.resolve(id: real.id, using: system) | ||
|
||
// just in order to see if we crash and trigger the accessible funcs printout | ||
_ = try await proxy.getArray(a1: [], a2: "") | ||
|
||
// === We expect records for accessible functions from other modules as well, | ||
// and especially we want to see records for the `$` macro generated stubs, | ||
// including | ||
|
||
// CHECK: ==== Accessible Function Records ==== | ||
// CHECK: Record name: $s16ResilientImplLib07ServiceB0C8getArray2a12a2Say0A6APILib8ResponseVGSaySiG_SSSgtYaKFTE | ||
// CHECK: Demangled: distributed thunk ResilientImplLib.ServiceImpl.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<ResilientAPILib.Response> | ||
|
||
// CHECK: Record name: $s15ResilientAPILib15ServiceProtocolPAA11Distributed01_E9ActorStubRzrlE8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTE | ||
// CHECK: Demangled: distributed thunk (extension in ResilientAPILib):ResilientAPILib.ServiceProtocol< where A: Distributed._DistributedActorStub>.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<ResilientAPILib.Response> | ||
|
||
// CHECK: Record name: $s15ResilientAPILib16$ServiceProtocolC8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTE | ||
// CHECK: Demangled: distributed thunk ResilientAPILib.$ServiceProtocol.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<ResilientAPILib.Response> | ||
|
||
// CHECK: Record name: $s4main15ServiceProtocolPAA11Distributed01_D9ActorStubRzrlE8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTE | ||
// CHECK: Demangled: distributed thunk (extension in main):main.ServiceProtocol< where A: Distributed._DistributedActorStub>.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<main.Response> | ||
|
||
// CHECK: Record name: $s4main11ServiceImplC8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTE | ||
// CHECK: Demangled: distributed thunk main.ServiceImpl.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<main.Response> | ||
|
||
// CHECK: Record name: $s4main16$ServiceProtocolC8getArray2a12a2SayAA8ResponseVGSaySiG_SSSgtYaKFTE | ||
// CHECK: Demangled: distributed thunk main.$ServiceProtocol.getArray(a1: Swift.Array<Swift.Int>, a2: Swift.Optional<Swift.String>) async throws -> Swift.Array<main.Response> | ||
|
||
// We expect these to be the exact records we get, no other ones: | ||
// CHECK: Record count: 6 | ||
|
||
// CHECK: ==== End of Accessible Function Records ==== | ||
|
||
print("DONE") // CHECK: DONE | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.