Skip to content

Commit 73b74a1

Browse files
committed
docs: add concurrency model documentation to ServerSession and _transition_state
Github-Issue: #1691
1 parent e00f990 commit 73b74a1

1 file changed

Lines changed: 17 additions & 0 deletions

File tree

src/mcp/server/session.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ class ServerSession(
124124
types.ClientNotification,
125125
]
126126
):
127+
"""Server-side MCP session.
128+
129+
Concurrency model: incoming messages are processed sequentially by a single
130+
``_receive_loop`` task spawned in ``BaseSession.__aenter__``. All state
131+
transitions driven by messages (``_received_request``, ``_received_notification``)
132+
therefore execute without concurrent interleaving. The only other code path
133+
that mutates ``_initialization_state`` is ``__aexit__``, which may overlap
134+
briefly with the receive loop before the task group is cancelled; that path
135+
already handles transition failures gracefully.
136+
"""
137+
127138
_initialization_state: InitializationState = InitializationState.NotInitialized
128139
_client_params: types.InitializeRequestParams | None = None
129140
_experimental_features: ExperimentalServerSessionFeatures | None = None
@@ -173,6 +184,12 @@ def is_initialized(self) -> bool:
173184
def _transition_state(self, new_state: InitializationState) -> None:
174185
"""Transition the session to a new state, validating the transition.
175186
187+
This method is intentionally synchronous (no ``await``), so under
188+
cooperative scheduling no task switch can occur between the validity
189+
check and the state assignment. External synchronization is therefore
190+
unnecessary as long as the single-consumer invariant documented on the
191+
class holds.
192+
176193
Args:
177194
new_state: The target state to transition to.
178195

0 commit comments

Comments
 (0)