Skip to content

Commit 64288b5

Browse files
author
dragogargo
committed
fix: add timeout to shielded cancel notification to prevent hangs
The shielded CancelScope in _send_cancelled_notification could block indefinitely if the write stream was full or closed during shutdown. Add a 2-second timeout inside the shield so the notification is best-effort but never blocks session cleanup.
1 parent 3d02bb5 commit 64288b5

1 file changed

Lines changed: 13 additions & 11 deletions

File tree

src/mcp/shared/session.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -548,20 +548,22 @@ async def send_progress_notification(
548548
async def _send_cancelled_notification(self, request_id: RequestId, reason: str) -> None:
549549
"""Send a cancellation notification to the remote side (best-effort).
550550
551-
Uses a shielded cancel scope so the notification is delivered even
552-
when called from inside a cancelled task.
551+
Uses a shielded cancel scope with a timeout so the notification is
552+
delivered even when called from inside a cancelled task, but does not
553+
block shutdown if the write stream is unavailable.
553554
"""
554555
try:
555556
with anyio.CancelScope(shield=True):
556-
notification = CancelledNotification(
557-
method="notifications/cancelled",
558-
params=CancelledNotificationParams(request_id=request_id, reason=reason),
559-
)
560-
jsonrpc_notification = JSONRPCNotification(
561-
jsonrpc="2.0",
562-
**notification.model_dump(by_alias=True, mode="json", exclude_none=True),
563-
)
564-
await self._write_stream.send(SessionMessage(message=jsonrpc_notification))
557+
with anyio.fail_after(2):
558+
notification = CancelledNotification(
559+
method="notifications/cancelled",
560+
params=CancelledNotificationParams(request_id=request_id, reason=reason),
561+
)
562+
jsonrpc_notification = JSONRPCNotification(
563+
jsonrpc="2.0",
564+
**notification.model_dump(by_alias=True, mode="json", exclude_none=True),
565+
)
566+
await self._write_stream.send(SessionMessage(message=jsonrpc_notification))
565567
except Exception:
566568
logging.warning("Failed to send cancellation notification for request %s", request_id)
567569

0 commit comments

Comments
 (0)