Skip to content

Commit 8872f9b

Browse files
committed
docs: add concurrency model documentation to ServerSession and _transition_state
Github-Issue: #1691
1 parent cf1bbd2 commit 8872f9b

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

0 commit comments

Comments
 (0)