@@ -28,23 +28,27 @@ struct LambdaMockWriter: LambdaResponseStreamWriter {
28
28
try await self . underlying. write ( buffer)
29
29
}
30
30
31
- consuming func finish( ) async throws {
31
+ func finish( ) async throws {
32
32
try await self . underlying. finish ( )
33
33
}
34
34
35
- consuming func writeAndFinish( _ buffer: ByteBuffer ) async throws {
36
- try await self . write ( buffer)
37
- try await self . finish ( )
35
+ func writeAndFinish( _ buffer: ByteBuffer ) async throws {
36
+ try await self . underlying . write ( buffer)
37
+ try await self . underlying . finish ( )
38
38
}
39
39
40
40
func reportError( _ error: any Error ) async throws {
41
+ try await self . underlying. write ( ByteBuffer ( string: " \( error) " ) )
42
+ try await self . underlying. finish ( )
41
43
}
42
44
}
43
45
44
46
enum LambdaError : Error , Equatable {
45
47
case cannotCallNextEndpointWhenAlreadyWaitingForEvent
46
48
case cannotCallNextEndpointWhenAlreadyProcessingAnEvent
47
49
case cannotReportResultWhenNoEventHasBeenProcessed
50
+ case cancelError
51
+ case handlerError
48
52
}
49
53
50
54
final actor LambdaMockClient : LambdaRuntimeClientProtocol {
@@ -89,6 +93,12 @@ final actor LambdaMockClient: LambdaRuntimeClientProtocol {
89
93
case fail( LambdaError )
90
94
}
91
95
96
+ enum CancelNextAction {
97
+ case none
98
+
99
+ case cancelContinuation( CheckedContinuation < Invocation , any Error > )
100
+ }
101
+
92
102
enum ResultAction {
93
103
case readyForMore
94
104
@@ -165,6 +175,16 @@ final actor LambdaMockClient: LambdaRuntimeClientProtocol {
165
175
throw LambdaError . cannotReportResultWhenNoEventHasBeenProcessed
166
176
}
167
177
}
178
+
179
+ mutating func cancelNext( ) -> CancelNextAction {
180
+ switch self . state {
181
+ case . initialState, . handlerIsProcessing:
182
+ return . none
183
+ case . waitingForNextEvent( let eventArrivedHandler) :
184
+ self . state = . initialState
185
+ return . cancelContinuation( eventArrivedHandler)
186
+ }
187
+ }
168
188
}
169
189
170
190
private var stateMachine : StateMachine = . init( )
@@ -208,18 +228,32 @@ final actor LambdaMockClient: LambdaRuntimeClientProtocol {
208
228
}
209
229
210
230
func nextInvocation( ) async throws -> ( Invocation , Writer ) {
211
- let invocation = try await withCheckedThrowingContinuation { eventArrivedHandler in
212
- switch self . stateMachine. next ( eventArrivedHandler) {
213
- case . readyToProcess( let event) :
214
- eventArrivedHandler. resume ( returning: event)
215
- case . fail( let error) :
216
- eventArrivedHandler. resume ( throwing: error)
217
- case . wait:
218
- break
231
+ try await withTaskCancellationHandler {
232
+ let invocation = try await withCheckedThrowingContinuation { eventArrivedHandler in
233
+ switch self . stateMachine. next ( eventArrivedHandler) {
234
+ case . readyToProcess( let event) :
235
+ eventArrivedHandler. resume ( returning: event)
236
+ case . fail( let error) :
237
+ eventArrivedHandler. resume ( throwing: error)
238
+ case . wait:
239
+ break
240
+ }
241
+ }
242
+ return ( invocation, Writer ( underlying: self ) )
243
+ } onCancel: {
244
+ Task {
245
+ await self . cancelNextInvocation ( )
219
246
}
220
247
}
248
+ }
221
249
222
- return ( invocation, Writer ( underlying: self ) )
250
+ private func cancelNextInvocation( ) {
251
+ switch self . stateMachine. cancelNext ( ) {
252
+ case . none:
253
+ break
254
+ case . cancelContinuation( let continuation) :
255
+ continuation. resume ( throwing: LambdaError . cancelError)
256
+ }
223
257
}
224
258
225
259
func write( _ buffer: ByteBuffer ) async throws {
0 commit comments