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