-
[SE-0548] resignRemoteID for remote distributed actor referencesSwift 2026. 9. 26. 18:12
안녕하세요. 그린입니다 🍏
이번 포스팅에서는 SE-0548 — 원격 분산 액터 참조를 위한 resignRemoteID에 대해 정리해보겠습니다 🙋🏻
Intro
Proposal: SE-0548
Author: Konrad 'ktoso' Malawski
Review Manager: Doug Gregor
Status: Accepted
Implementation: swiftlang/swift#91610
Summary of Changes
분산 액터(distributed actor)의 정체성은 연관된
DistributedActorSystem이 관리해요.지금까지 시스템은
assignID(_:)/resignID(_:)쌍을 통해 로컬 분산 액터 인스턴스의 생명주기를 관찰하고,resolve(id:as:)를 통해 원격 참조의 생성에 관여했어요.하지만 원격 참조가 언제 deinitialize되는지 관찰할 방법은 없었습니다.
이 제안은 원격 분산 액터 프록시가 deinitialize될 때 호출되는 새 프로토콜 요구사항
resignRemoteID(_:)하나를 추가하자고 제안합니다.Motivation
SE-0344: Distributed Actor Runtime는
DistributedActorSystem에 다음과 같은 생명주기 콜백들을 정의해요.assignID(_:): 로컬 분산 액터가 초기화되는 중에 정체성(identity)을 얻기 위해 호출됨actorReady(_:): 로컬 분산 액터가 초기화를 완료했을 때 호출됨resignID(_:): 로컬 분산 액터가 deinitialize될 때(또는 초기화가 실패할 때) 호출됨resolve(id:as:): 사용자 코드가SomeActor.resolve(id:using:)를 호출할 때 실행됨.nil을 반환하면 런타임에게 이id에 대한 원격 참조를 할당하라고 알려줌
원격 경로의 생명주기는 비대칭적이에요.
resolve(id:as:)는 원격 참조를 생성할 때 호출되지만, 그 참조들에 대해resignID와 대응되는 콜백은 없습니다.원격 참조가 상태가 없고 리소스를 들고 있지 않은 시스템이라면 이걸로 충분해요.
하지만 예를 들어 특정 커넥션을 쓰고 있는 원격 액터 참조가 최소 하나라도 존재하는 동안엔 그 커넥션을 계속 살려두고 싶은 시스템에는 문제가 되는 것으로 나타났습니다.
이상적으로는, 원격 참조가 할당 해제될 때마다 시스템이 통지받아서, 그 id를 이용해 커넥션을 이미 종료해도 되는지 아직 안 되는지를 관리할 수 있어야 합니다.
Proposed Solution
원격 분산 액터 참조가 deinitialize될 때 호출되는 새 프로토콜 요구사항을
DistributedActorSystem에 추가해서 이 문제를 해결하자고 제안합니다.public protocol DistributedActorSystem { // ... existing requirements, including: func resignID(_ id: ActorID) /// Invoked when a remote distributed actor reference is deinitializing. /// /// The passed in ID, generally, would have been passed to \`resolve(id:as:)\` earlier /// and a remote distributed reference would have been created as a result of that resolve call. /// /// - SeeAlso: \`\`resignID(_:)\`\` which is invoked for local instances. func resignRemoteID(_ id: ActorID) } extension DistributedActorSystem { public func resignRemoteID(_ id: ActorID) {} }Swift 런타임은 원격 분산 액터 프록시의
deinit이 실행될 때resignRemoteID(_:)를 호출하도록 업데이트돼요.기존
resignID(_:)는 계속 로컬 인스턴스에 대해서만 호출됩니다.Detailed Design
구현 수준에서, 프로토콜 요구사항을 도입하는 것 외의 유일한 변경은 원격 분산 액터의 deinit에서 이걸 실제로 호출하는 것뿐이에요.
deinit { // if { // << actorSystem.resignRemoteID(self.id) // NEW // << deallocate memory for \`id\` and \`actorSystem\` only // } else if { // << run user-declared deinit body // << actorSystem.resignID(self.id) // << deallocate all stored properties // } }사용자가 선언한
deinit본문은 원격 참조에서는 여전히 절대 실행되지 않고, 기존resignID경로도 변경되지 않은 채로 유지됩니다.이 결과로 생명주기 관리는 다음과 같이 정리돼요.
"Local instance" 분산 액터 "Remote reference" 분산 액터 Registration init 중 assignID(_:)resolve(id:as:)가nil반환Ready init 후 actorReady(_:)N/A Deinit deinit 시 resignID(_:)deinit 시 resignRemoteID(_:)resolve는 같은 id로 여러 번 호출될 수 있기 때문에,resignRemoteID도 같은 id로 여러 번 호출될 수 있어요.resolve로 생성된 원격 참조마다 한 번씩요.새로 추가된 resignRemoteID(_:)는 "대응되는" resolve(id:as:)가 다음과 같은 경우엔 호출되지 않아요.
- 에러를 던진 경우 (참조가 생성되지 않음)
- 로컬 액터를 반환한 경우 (원격 참조가 아니라 로컬 경로가 적용됨)
Source Compatibility
기존
DistributedActorSystem구현체들은 계속 컴파일되고 동일하게 동작합니다.ABI Compatibility
DistributedActorSystem은 기본 구현이 있는 새 요구사항을 하나 추가로 얻는데, 이건 기존 구현체들에 대해 소스/ABI 호환적이에요.분산 액터의 deinit에 새로 추가되는 SILGen 호출 지점은 back-deployment 호환적이라, 이 요구사항이 없는 옛날 런타임에 새로 컴파일된 코드를 배포하는 것도 가능해요.
그런 경우엔 그냥 그 호출이 일어나지 않을 뿐입니다.
Alternatives Considered
그냥 resignID를 원격 참조에도 재사용하기
가장 쉬운 해법은
resignID가 원격 참조를 포함해서 항상 호출되도록 동작을 바꾸는 것일 거예요.여기엔 두 가지 문제가 있어요.
resignID메서드의 문서는 개발자들에게 자신이 할당하지 않은 id가 전달되면 크래시내라고 권장해왔어요.
그게 액터 시스템의 오작동을 나타낸다고 봤기 때문이에요.
실제로는 그런 값을 무시해도 완전히 안전하니 이 가이드는 너무 보수적이었던 셈이지만, 실제로 크래시내는 시스템이 있다면 새 Swift 버전에서 동작이 바뀌었을 때 새롭게 크래시가 나기 시작할 수 있어요.- 실제로는 이 리스크가 작은 편인데, 우리가 아는 액터 시스템들은 "알 수 없는 ID" 케이스를 허용하도록 쉽게 업데이트해서 계속 동작하게 만들 수 있기 때문이에요.
- "resign"이라는 의미에 과부하가 걸리고, assign/resign 짝과도 잘 안 어울려요.
이 메서드들은 더 이상 짝이 아니게 되고, resolve-remote 경로에는 호출될 "짝"이 없어져서 resign을 구현하기가 더 어려워져요 (어떤 경로를 타야 하는지 추적해야 하니까요).
Conclusion
그동안 분산 액터의 원격 참조는 언제 사라지는지 시스템이 알 방법이 없어서, 커넥션처럼 원격 참조 개수에 따라 살았다 죽었다 해야 하는 리소스를 관리하기가 까다로웠어요.
resignRemoteID(_:)하나만 추가해서assignID/resignID짝처럼 로컬과 원격 양쪽 모두 대칭적인 생명주기 콜백을 갖추게 됐다는 점이 좋은 포인트인것 같습니다 👍기본 구현이 빈 함수라 기존 구현체에 아무 영향도 주지 않으면서 필요한 시스템만 채택하면 되는 점도 실용적입니다 🙌
References
swift-evolution/proposals/0548-resign-remote-id.md at main · swiftlang/swift-evolution
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution
github.com
'Swift' 카테고리의 다른 글
[SE-0541] Flexible Swift/C Interoperability for Packages (2) 2026.09.20 [SE-0544] Mutation and consumption in non-Copyable type deinits (6) 2026.08.31 [SE-0538] Disconnected (0) 2026.08.22 [SE-0537] Section Placement Control for Functions (2) 2026.08.15 [SE-0535] Add CLI for editing global mirrors configuration (0) 2026.08.08