@@ -406,6 +406,17 @@ private protocol LambdaChannelHandlerDelegate {
406
406
func connectionErrorHappened( _ error: any Error , channel: any Channel )
407
407
}
408
408
409
+ struct UnsafeContext : @unchecked Sendable {
410
+ private let _context : ChannelHandlerContext
411
+ var context : ChannelHandlerContext {
412
+ self . _context. eventLoop. preconditionInEventLoop ( )
413
+ return _context
414
+ }
415
+ init ( _ context: ChannelHandlerContext ) {
416
+ self . _context = context
417
+ }
418
+ }
419
+
409
420
private final class LambdaChannelHandler < Delegate: LambdaChannelHandlerDelegate > {
410
421
let nextInvocationPath = Consts . invocationURLPrefix + Consts. getNextInvocationURLSuffix
411
422
@@ -465,10 +476,37 @@ private final class LambdaChannelHandler<Delegate: LambdaChannelHandlerDelegate>
465
476
func nextInvocation( isolation: isolated ( any Actor ) ? = #isolation) async throws -> Invocation {
466
477
switch self . state {
467
478
case . connected( let context, . idle) :
468
- return try await withCheckedThrowingContinuation {
469
- ( continuation: CheckedContinuation < Invocation , any Error > ) in
470
- self . state = . connected( context, . waitingForNextInvocation( continuation) )
471
- self . sendNextRequest ( context: context)
479
+ return try await withTaskCancellationHandler {
480
+ try Task . checkCancellation ( )
481
+ return try await withCheckedThrowingContinuation {
482
+ ( continuation: CheckedContinuation < Invocation , any Error > ) in
483
+ self . state = . connected( context, . waitingForNextInvocation( continuation) )
484
+
485
+ let unsafeContext = UnsafeContext ( context)
486
+ context. eventLoop. execute { [ nextInvocationPath, defaultHeaders] in
487
+ // Send next request. The function `sendNextRequest` requires `self` which is not
488
+ // Sendable so just inlined the code instead
489
+ let httpRequest = HTTPRequestHead (
490
+ version: . http1_1,
491
+ method: . GET,
492
+ uri: nextInvocationPath,
493
+ headers: defaultHeaders
494
+ )
495
+ let context = unsafeContext. context
496
+ context. write ( Self . wrapOutboundOut ( . head( httpRequest) ) , promise: nil )
497
+ context. write ( Self . wrapOutboundOut ( . end( nil ) ) , promise: nil )
498
+ context. flush ( )
499
+ }
500
+ }
501
+ } onCancel: {
502
+ switch self . state {
503
+ case . connected( _, . waitingForNextInvocation( let continuation) ) :
504
+ continuation. resume ( throwing: CancellationError ( ) )
505
+ case . connected( _, . idle) :
506
+ break
507
+ default :
508
+ fatalError ( " Invalid state: \( self . state) " )
509
+ }
472
510
}
473
511
474
512
case . connected( _, . sendingResponse) ,
0 commit comments