1111//===----------------------------------------------------------------------===//
1212
1313import Swift
14- import _Concurrency
1514
1615#if canImport(Darwin)
1716import Darwin
@@ -27,33 +26,25 @@ import WinSDK
2726/// for learning about `distributed actor` isolation, as well as early
2827/// prototyping stages of development where a real system is not necessary yet.
2928@available ( SwiftStdlib 5 . 7 , * )
30- public struct LocalTestingDistributedActorSystem : DistributedActorSystem , @unchecked Sendable {
29+ public final class LocalTestingDistributedActorSystem : DistributedActorSystem , @unchecked Sendable {
3130 public typealias ActorID = LocalTestingActorAddress
3231 public typealias ResultHandler = LocalTestingInvocationResultHandler
3332 public typealias InvocationEncoder = LocalTestingInvocationEncoder
3433 public typealias InvocationDecoder = LocalTestingInvocationDecoder
35- public typealias SerializationRequirement = any Codable
36-
37-
38- @usableFromInline
39- final class _Storage {
34+ public typealias SerializationRequirement = Codable
4035
41- var activeActors : [ ActorID : any DistributedActor ] = [ : ]
42- let activeActorsLock = _Lock ( )
36+ private var activeActors : [ ActorID : any DistributedActor ] = [ : ]
37+ private let activeActorsLock = _Lock ( )
4338
44- var assignedIDs : Set < ActorID > = [ ]
45- let assignedIDsLock = _Lock ( )
46- }
47- let storage : _Storage
48- var idProvider : ActorIDProvider = ActorIDProvider ( )
39+ private var idProvider : ActorIDProvider = ActorIDProvider ( )
40+ private var assignedIDs : Set < ActorID > = [ ]
41+ private let assignedIDsLock = _Lock ( )
4942
50- public init ( ) {
51- storage = . init( )
52- }
43+ public init ( ) { }
5344
5445 public func resolve< Act> ( id: ActorID , as actorType: Act . Type )
55- throws -> Act ? where Act: DistributedActor , Act . ID == ActorID {
56- guard let anyActor = storage . activeActorsLock. withLock ( { self . storage . activeActors [ id] } ) else {
46+ throws -> Act ? where Act: DistributedActor {
47+ guard let anyActor = self . activeActorsLock. withLock ( { self . activeActors [ id] } ) else {
5748 throw LocalTestingDistributedActorSystemError ( message: " Unable to locate id ' \( id) ' locally " )
5849 }
5950 guard let actor = anyActor as? Act else {
@@ -63,25 +54,28 @@ public struct LocalTestingDistributedActorSystem: DistributedActorSystem, @unche
6354 }
6455
6556 public func assignID< Act> ( _ actorType: Act . Type ) -> ActorID
66- where Act: DistributedActor , Act . ID == ActorID {
57+ where Act: DistributedActor {
6758 let id = self . idProvider. next ( )
68- storage . assignedIDsLock. withLock {
69- self . storage . assignedIDs. insert ( id)
59+ self . assignedIDsLock. withLock {
60+ self . assignedIDs. insert ( id)
7061 }
7162 return id
7263 }
7364
7465 public func actorReady< Act> ( _ actor : Act )
75- where Act: DistributedActor , Act. ID == ActorID {
76- guard storage. assignedIDsLock. withLock ( { self . storage. assignedIDs. contains ( actor . id) } ) else {
66+ where Act: DistributedActor ,
67+ Act. ID == ActorID {
68+ guard self . assignedIDsLock. withLock ( { self . assignedIDs. contains ( actor . id) } ) else {
7769 fatalError ( " Attempted to mark an unknown actor ' \( actor . id) ' ready " )
7870 }
79- self . storage. activeActors [ actor . id] = actor
71+ self . activeActorsLock. withLock {
72+ self . activeActors [ actor . id] = actor
73+ }
8074 }
8175
8276 public func resignID( _ id: ActorID ) {
83- storage . activeActorsLock. withLock {
84- self . storage . activeActors. removeValue ( forKey: id)
77+ self . activeActorsLock. withLock {
78+ self . activeActors. removeValue ( forKey: id)
8579 }
8680 }
8781
@@ -99,7 +93,7 @@ public struct LocalTestingDistributedActorSystem: DistributedActorSystem, @unche
9993 where Act: DistributedActor ,
10094 Act. ID == ActorID ,
10195 Err: Error ,
102- Res: Codable {
96+ Res: SerializationRequirement {
10397 fatalError ( " Attempted to make remote call to \( target) on actor \( actor ) using a local-only actor system " )
10498 }
10599
@@ -115,40 +109,51 @@ public struct LocalTestingDistributedActorSystem: DistributedActorSystem, @unche
115109 fatalError ( " Attempted to make remote call to \( target) on actor \( actor ) using a local-only actor system " )
116110 }
117111
118- @usableFromInline
119- final class ActorIDProvider {
112+ private struct ActorIDProvider {
120113 private var counter : Int = 0
121114 private let counterLock = _Lock ( )
122115
123- @usableFromInline
124116 init ( ) { }
125117
126- func next( ) -> LocalTestingActorAddress {
118+ mutating func next( ) -> LocalTestingActorAddress {
127119 let id : Int = self . counterLock. withLock {
128120 self . counter += 1
129121 return self . counter
130122 }
131- return LocalTestingActorAddress ( id )
123+ return LocalTestingActorAddress ( parse : " \( id ) " )
132124 }
133125 }
134126}
135127
136128@available ( SwiftStdlib 5 . 7 , * )
137- public struct LocalTestingActorAddress : Hashable , Sendable , Codable {
138- public let uuid : String
129+ @available ( * , deprecated, renamed: " LocalTestingActorID " )
130+ public typealias LocalTestingActorAddress = LocalTestingActorID
131+
132+ @available ( SwiftStdlib 5 . 7 , * )
133+ public struct LocalTestingActorID : Hashable , Sendable , Codable {
134+ @available ( * , deprecated, renamed: " id " )
135+ public var address : String {
136+ self . id
137+ }
138+ public let id : String
139+
140+ @available ( * , deprecated, renamed: " init(id:) " )
141+ public init ( parse id: String ) {
142+ self . id = id
143+ }
139144
140- public init ( _ uuid : Int ) {
141- self . uuid = " \( uuid ) "
145+ public init ( id : String ) {
146+ self . id = id
142147 }
143148
144149 public init ( from decoder: Decoder ) throws {
145150 let container = try decoder. singleValueContainer ( )
146- self . uuid = try container. decode ( String . self)
151+ self . id = try container. decode ( String . self)
147152 }
148153
149154 public func encode( to encoder: Encoder ) throws {
150155 var container = encoder. singleValueContainer ( )
151- try container. encode ( self . uuid )
156+ try container. encode ( self . id )
152157 }
153158}
154159
@@ -228,7 +233,7 @@ public struct LocalTestingDistributedActorSystemError: DistributedActorSystemErr
228233// === lock ----------------------------------------------------------------
229234
230235@available ( SwiftStdlib 5 . 7 , * )
231- internal class _Lock {
236+ fileprivate class _Lock {
232237 #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
233238 private let underlying : UnsafeMutablePointer < os_unfair_lock >
234239 #elseif os(Windows)
@@ -241,27 +246,10 @@ internal class _Lock {
241246 private let underlying : UnsafeMutablePointer < pthread_mutex_t >
242247 #endif
243248
244- init ( ) {
245- #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
246- self . underlying = UnsafeMutablePointer . allocate ( capacity: 1 )
247- self . underlying. initialize ( to: os_unfair_lock ( ) )
248- #elseif os(Windows)
249- self . underlying = UnsafeMutablePointer . allocate ( capacity: 1 )
250- InitializeSRWLock ( self . underlying)
251- #elseif os(WASI)
252- // WASI environment has only a single thread
253- #else
254- self . underlying = UnsafeMutablePointer . allocate ( capacity: 1 )
255- guard pthread_mutex_init ( self . underlying, nil ) == 0 else {
256- fatalError ( " pthread_mutex_init failed " )
257- }
258- #endif
259- }
260-
261249 deinit {
262250 #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
263251 // `os_unfair_lock`s do not need to be explicitly destroyed
264- #elseif os(Windows)
252+ #elseif os(Windows)
265253 // `SRWLOCK`s do not need to be explicitly destroyed
266254 #elseif os(WASI)
267255 // WASI environment has only a single thread
@@ -277,6 +265,22 @@ internal class _Lock {
277265 #endif
278266 }
279267
268+ init ( ) {
269+ #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
270+ self . underlying = UnsafeMutablePointer . allocate ( capacity: 1 )
271+ #elseif os(Windows)
272+ self . underlying = UnsafeMutablePointer . allocate ( capacity: 1 )
273+ InitializeSRWLock ( self . underlying)
274+ #elseif os(WASI)
275+ // WASI environment has only a single thread
276+ #else
277+ self . underlying = UnsafeMutablePointer . allocate ( capacity: 1 )
278+ guard pthread_mutex_init ( self . underlying, nil ) == 0 else {
279+ fatalError ( " pthread_mutex_init failed " )
280+ }
281+ #endif
282+ }
283+
280284 @discardableResult
281285 func withLock< T> ( _ body: ( ) -> T ) -> T {
282286 #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
0 commit comments