@@ -459,7 +459,14 @@ import Logging
459459 content: Heartbeat ( ) . data,
460460 contentContext: . defaultMessage,
461461 isComplete: true ,
462- completion: . contentProcessed { [ weak self] error in
462+ completion: . contentProcessed { [ weak self, continuation] error in
463+ guard let self = self else {
464+ continuation. resume (
465+ throwing: MCPError . internalError (
466+ " Transport deallocated during heartbeat " ) )
467+ return
468+ }
469+
463470 if let error = error {
464471 continuation. resume ( throwing: error)
465472 } else {
@@ -511,9 +518,6 @@ import Logging
511518 var messageWithNewline = message
512519 messageWithNewline. append ( UInt8 ( ascii: " \n " ) )
513520
514- // Use a local actor-isolated variable to track continuation state
515- var sendContinuationResumed = false
516-
517521 try await withCheckedThrowingContinuation {
518522 [ weak self] ( continuation: CheckedContinuation < Void , Swift . Error > ) in
519523 guard let self = self else {
@@ -525,50 +529,43 @@ import Logging
525529 content: messageWithNewline,
526530 contentContext: . defaultMessage,
527531 isComplete: true ,
528- completion: . contentProcessed { [ weak self] error in
529- guard let self = self else { return }
530-
531- Task { @MainActor in
532- if !sendContinuationResumed {
533- sendContinuationResumed = true
534- if let error = error {
535- self . logger. error ( " Send error: \( error) " )
536-
537- // Check if we should attempt to reconnect on send failure
538- let isStopping = await self . isStopping // Await actor-isolated property
539- if !isStopping && self . reconnectionConfig. enabled {
540- let isConnected = await self . isConnected
541- if isConnected {
542- if error. isConnectionLost {
543- self . logger. warning (
544- " Connection appears broken, will attempt to reconnect... "
545- )
546-
547- // Schedule connection restart
548- Task { [ weak self] in // Operate on self's executor
549- guard let self = self else { return }
550-
551- await self . setIsConnected ( false )
552-
553- try ? await Task . sleep ( for: . milliseconds( 500 ) )
554-
555- let currentIsStopping = await self . isStopping
556- if !currentIsStopping {
557- // Cancel the connection, then attempt to reconnect fully.
558- self . connection. cancel ( )
559- try ? await self . connect ( )
560- }
561- }
562- }
532+ completion: . contentProcessed { [ weak self, continuation] error in
533+ guard let self = self else {
534+ continuation. resume (
535+ throwing: MCPError . internalError (
536+ " Transport deallocated during send " ) )
537+ return
538+ }
539+
540+ if let error = error {
541+ self . logger. error ( " Send error: \( error) " )
542+
543+ // Schedule reconnection check on a separate task
544+ Task { [ weak self] in
545+ guard let self = self else { return }
546+ let isStopping = await self . isStopping
547+ if !isStopping && self . reconnectionConfig. enabled {
548+ let isConnected = await self . isConnected
549+ if isConnected && error. isConnectionLost {
550+ self . logger. warning (
551+ " Connection appears broken, will attempt to reconnect... "
552+ )
553+ await self . setIsConnected ( false )
554+ try ? await Task . sleep ( for: . milliseconds( 500 ) )
555+
556+ let currentIsStopping = await self . isStopping
557+ if !currentIsStopping {
558+ self . connection. cancel ( )
559+ try ? await self . connect ( )
563560 }
564561 }
565-
566- continuation. resume (
567- throwing: MCPError . internalError ( " Send error: \( error) " ) )
568- } else {
569- continuation. resume ( )
570562 }
571563 }
564+
565+ continuation. resume (
566+ throwing: MCPError . internalError ( " Send error: \( error) " ) )
567+ } else {
568+ continuation. resume ( )
572569 }
573570 } )
574571 }
@@ -747,8 +744,6 @@ import Logging
747744 /// - Returns: The received data chunk
748745 /// - Throws: Network errors or transport failures
749746 private func receiveData( ) async throws -> Data {
750- var receiveContinuationResumed = false
751-
752747 return try await withCheckedThrowingContinuation {
753748 [ weak self] ( continuation: CheckedContinuation < Data , Swift . Error > ) in
754749 guard let self = self else {
@@ -758,22 +753,16 @@ import Logging
758753
759754 let maxLength = bufferConfig. maxReceiveBufferSize ?? Int . max
760755 connection. receive ( minimumIncompleteLength: 1 , maximumLength: maxLength) {
761- content, _, isComplete, error in
762- Task { @MainActor in
763- if !receiveContinuationResumed {
764- receiveContinuationResumed = true
765- if let error = error {
766- continuation. resume ( throwing: MCPError . transportError ( error) )
767- } else if let content = content {
768- continuation. resume ( returning: content)
769- } else if isComplete {
770- self . logger. trace ( " Connection completed by peer " )
771- continuation. resume ( throwing: MCPError . connectionClosed)
772- } else {
773- // EOF: Resume with empty data instead of throwing an error
774- continuation. resume ( returning: Data ( ) )
775- }
776- }
756+ [ weak self, continuation] content, _, isComplete, error in
757+ if let error = error {
758+ continuation. resume ( throwing: MCPError . transportError ( error) )
759+ } else if let content = content {
760+ continuation. resume ( returning: content)
761+ } else if isComplete {
762+ self ? . logger. trace ( " Connection completed by peer " )
763+ continuation. resume ( throwing: MCPError . connectionClosed)
764+ } else {
765+ continuation. resume ( returning: Data ( ) )
777766 }
778767 }
779768 }
0 commit comments