11
11
//===----------------------------------------------------------------------===//
12
12
13
13
import Swift
14
- import _Concurrency
15
14
16
15
#if canImport(Darwin)
17
16
import Darwin
@@ -27,33 +26,25 @@ import WinSDK
27
26
/// for learning about `distributed actor` isolation, as well as early
28
27
/// prototyping stages of development where a real system is not necessary yet.
29
28
@available ( SwiftStdlib 5 . 7 , * )
30
- public struct LocalTestingDistributedActorSystem : DistributedActorSystem , @unchecked Sendable {
29
+ public final class LocalTestingDistributedActorSystem : DistributedActorSystem , @unchecked Sendable {
31
30
public typealias ActorID = LocalTestingActorAddress
32
31
public typealias ResultHandler = LocalTestingInvocationResultHandler
33
32
public typealias InvocationEncoder = LocalTestingInvocationEncoder
34
33
public typealias InvocationDecoder = LocalTestingInvocationDecoder
35
- public typealias SerializationRequirement = any Codable
36
-
37
-
38
- @usableFromInline
39
- final class _Storage {
34
+ public typealias SerializationRequirement = Codable
40
35
41
- var activeActors : [ ActorID : any DistributedActor ] = [ : ]
42
- let activeActorsLock = _Lock ( )
36
+ private var activeActors : [ ActorID : any DistributedActor ] = [ : ]
37
+ private let activeActorsLock = _Lock ( )
43
38
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 ( )
49
42
50
- public init ( ) {
51
- storage = . init( )
52
- }
43
+ public init ( ) { }
53
44
54
45
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 {
57
48
throw LocalTestingDistributedActorSystemError ( message: " Unable to locate id ' \( id) ' locally " )
58
49
}
59
50
guard let actor = anyActor as? Act else {
@@ -63,25 +54,28 @@ public struct LocalTestingDistributedActorSystem: DistributedActorSystem, @unche
63
54
}
64
55
65
56
public func assignID< Act> ( _ actorType: Act . Type ) -> ActorID
66
- where Act: DistributedActor , Act . ID == ActorID {
57
+ where Act: DistributedActor {
67
58
let id = self . idProvider. next ( )
68
- storage . assignedIDsLock. withLock {
69
- self . storage . assignedIDs. insert ( id)
59
+ self . assignedIDsLock. withLock {
60
+ self . assignedIDs. insert ( id)
70
61
}
71
62
return id
72
63
}
73
64
74
65
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 {
77
69
fatalError ( " Attempted to mark an unknown actor ' \( actor . id) ' ready " )
78
70
}
79
- self . storage. activeActors [ actor . id] = actor
71
+ self . activeActorsLock. withLock {
72
+ self . activeActors [ actor . id] = actor
73
+ }
80
74
}
81
75
82
76
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)
85
79
}
86
80
}
87
81
@@ -99,7 +93,7 @@ public struct LocalTestingDistributedActorSystem: DistributedActorSystem, @unche
99
93
where Act: DistributedActor ,
100
94
Act. ID == ActorID ,
101
95
Err: Error ,
102
- Res: Codable {
96
+ Res: SerializationRequirement {
103
97
fatalError ( " Attempted to make remote call to \( target) on actor \( actor ) using a local-only actor system " )
104
98
}
105
99
@@ -115,40 +109,51 @@ public struct LocalTestingDistributedActorSystem: DistributedActorSystem, @unche
115
109
fatalError ( " Attempted to make remote call to \( target) on actor \( actor ) using a local-only actor system " )
116
110
}
117
111
118
- @usableFromInline
119
- final class ActorIDProvider {
112
+ private struct ActorIDProvider {
120
113
private var counter : Int = 0
121
114
private let counterLock = _Lock ( )
122
115
123
- @usableFromInline
124
116
init ( ) { }
125
117
126
- func next( ) -> LocalTestingActorAddress {
118
+ mutating func next( ) -> LocalTestingActorAddress {
127
119
let id : Int = self . counterLock. withLock {
128
120
self . counter += 1
129
121
return self . counter
130
122
}
131
- return LocalTestingActorAddress ( id )
123
+ return LocalTestingActorAddress ( parse : " \( id ) " )
132
124
}
133
125
}
134
126
}
135
127
136
128
@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
+ }
139
144
140
- public init ( _ uuid : Int ) {
141
- self . uuid = " \( uuid ) "
145
+ public init ( id : String ) {
146
+ self . id = id
142
147
}
143
148
144
149
public init ( from decoder: Decoder ) throws {
145
150
let container = try decoder. singleValueContainer ( )
146
- self . uuid = try container. decode ( String . self)
151
+ self . id = try container. decode ( String . self)
147
152
}
148
153
149
154
public func encode( to encoder: Encoder ) throws {
150
155
var container = encoder. singleValueContainer ( )
151
- try container. encode ( self . uuid )
156
+ try container. encode ( self . id )
152
157
}
153
158
}
154
159
@@ -228,7 +233,7 @@ public struct LocalTestingDistributedActorSystemError: DistributedActorSystemErr
228
233
// === lock ----------------------------------------------------------------
229
234
230
235
@available ( SwiftStdlib 5 . 7 , * )
231
- internal class _Lock {
236
+ fileprivate class _Lock {
232
237
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
233
238
private let underlying : UnsafeMutablePointer < os_unfair_lock >
234
239
#elseif os(Windows)
@@ -241,27 +246,10 @@ internal class _Lock {
241
246
private let underlying : UnsafeMutablePointer < pthread_mutex_t >
242
247
#endif
243
248
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
-
261
249
deinit {
262
250
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
263
251
// `os_unfair_lock`s do not need to be explicitly destroyed
264
- #elseif os(Windows)
252
+ #elseif os(Windows)
265
253
// `SRWLOCK`s do not need to be explicitly destroyed
266
254
#elseif os(WASI)
267
255
// WASI environment has only a single thread
@@ -277,6 +265,22 @@ internal class _Lock {
277
265
#endif
278
266
}
279
267
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
+
280
284
@discardableResult
281
285
func withLock< T> ( _ body: ( ) -> T ) -> T {
282
286
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
0 commit comments