@@ -114,16 +114,6 @@ final actor LambdaRuntimeClient: LambdaRuntimeClientProtocol {
114
114
115
115
private var connectionState : ConnectionState = . disconnected
116
116
117
- // adding this dynamic property because I can not give access to `connectionState` directly
118
- // because it is private, depending on multiple private and non-Sendable types
119
- // the only thing we need to know outside of this class is if the connection state is disconnected
120
- @usableFromInline
121
- var didLooseConnection : Bool {
122
- get {
123
- self . connectionState == . lostConnection
124
- }
125
- }
126
-
127
117
private var lambdaState : LambdaState = . idle( previousRequestID: nil )
128
118
private var closingState : ClosingState = . notClosing
129
119
@@ -146,7 +136,6 @@ final actor LambdaRuntimeClient: LambdaRuntimeClientProtocol {
146
136
result = . failure( error)
147
137
}
148
138
await runtime. close ( )
149
-
150
139
return try result. get ( )
151
140
}
152
141
@@ -182,22 +171,27 @@ final actor LambdaRuntimeClient: LambdaRuntimeClientProtocol {
182
171
183
172
case . connected( let channel, _) :
184
173
channel. close ( mode: . all, promise: nil )
174
+
185
175
case . lostConnection:
186
- // this should never happen.
187
- fatalError ( " Lost connection to Lambda service while closing the runtime client " )
176
+ continuation. resume ( )
188
177
}
189
178
}
190
179
}
191
180
192
181
@usableFromInline
193
182
func nextInvocation( ) async throws -> ( Invocation , Writer ) {
194
183
195
- try await withTaskCancellationHandler {
184
+ if self . connectionState == . lostConnection {
185
+ throw LambdaRuntimeError ( code: . connectionToControlPlaneLost)
186
+ }
187
+
188
+ return try await withTaskCancellationHandler {
196
189
switch self . lambdaState {
197
190
case . idle:
198
191
self . lambdaState = . waitingForNextInvocation
199
192
let handler = try await self . makeOrGetConnection ( )
200
193
let invocation = try await handler. nextInvocation ( )
194
+
201
195
guard case . waitingForNextInvocation = self . lambdaState else {
202
196
fatalError ( " Invalid state: \( self . lambdaState) " )
203
197
}
@@ -312,7 +306,7 @@ final actor LambdaRuntimeClient: LambdaRuntimeClientProtocol {
312
306
case ( . connecting( let array) , . notClosing) :
313
307
self . connectionState = . disconnected
314
308
for continuation in array {
315
- continuation. resume ( throwing: LambdaRuntimeError ( code: . lostConnectionToControlPlane ) )
309
+ continuation. resume ( throwing: LambdaRuntimeError ( code: . connectionToControlPlaneLost ) )
316
310
}
317
311
318
312
case ( . connecting( let array) , . closing( let continuation) ) :
@@ -326,6 +320,7 @@ final actor LambdaRuntimeClient: LambdaRuntimeClientProtocol {
326
320
case ( . connected, . notClosing) :
327
321
self . connectionState = . disconnected
328
322
323
+
329
324
case ( . connected, . closing( let continuation) ) :
330
325
self . connectionState = . disconnected
331
326
@@ -398,13 +393,24 @@ final actor LambdaRuntimeClient: LambdaRuntimeClientProtocol {
398
393
)
399
394
channel. closeFuture. whenComplete { result in
400
395
self . assumeIsolated { runtimeClient in
396
+
397
+ // resume any pending continuation on the handler
398
+ if case . connected( _ , let handler) = runtimeClient. connectionState {
399
+ if case . connected( _ , let lambdaState) = handler. state {
400
+ if case . waitingForNextInvocation( let continuation) = lambdaState {
401
+ continuation. resume ( throwing: LambdaRuntimeError ( code: . connectionToControlPlaneLost) )
402
+ }
403
+ }
404
+ }
405
+
406
+ // close the channel
401
407
runtimeClient. channelClosed ( channel)
402
408
runtimeClient. connectionState = . lostConnection
403
409
}
404
410
}
405
411
406
412
switch self . connectionState {
407
- case . disconnected, . connected, . lostConnection :
413
+ case . disconnected, . connected:
408
414
fatalError ( " Unexpected state: \( self . connectionState) " )
409
415
410
416
case . connecting( let array) :
@@ -416,11 +422,14 @@ final actor LambdaRuntimeClient: LambdaRuntimeClientProtocol {
416
422
}
417
423
}
418
424
return handler
425
+ case . lostConnection:
426
+ // this should never happen
427
+ fatalError ( " Lost connection to Lambda service " )
419
428
}
420
429
} catch {
421
430
422
431
switch self . connectionState {
423
- case . disconnected, . connected, . lostConnection :
432
+ case . disconnected, . connected:
424
433
fatalError ( " Unexpected state: \( self . connectionState) " )
425
434
426
435
case . connecting( let array) :
@@ -431,6 +440,9 @@ final actor LambdaRuntimeClient: LambdaRuntimeClientProtocol {
431
440
}
432
441
}
433
442
throw error
443
+ case . lostConnection:
444
+ // this should never happen
445
+ fatalError ( " Lost connection to Lambda service " )
434
446
}
435
447
}
436
448
}
0 commit comments