Skip to content

Simplify and harden session lifecycle with an explicit state machine #1691

Description

@dgenio

Description

Summary

Server and client sessions use an internal initialization state machine combined with various flags and manual AsyncExitStack management. Stateless mode complicates this further by setting an "Initialized" state early as a workaround.

This makes the lifecycle hard to reason about and contributes to subtle bugs (e.g., past issues like #756 in stateless mode).

Problems

  • Scattered state management: Initialization and teardown logic are spread across methods and files.
  • Special cases for stateless mode: Stateless HTTP sets the session as initialized even though no real protocol negotiation has occurred.
  • Resource management risk: If initialization fails midway, transport tasks and resources may not be cleaned up reliably.
  • Testing difficulty: Tests often bypass parts of the lifecycle using in-memory transports.

Proposal

  1. Introduce an explicit session state machine

    Represent distinct states as separate types, for example:

    • UninitializedSession
    • NegotiatingSession
    • ActiveSession
    • ClosedSession
    • StatelessSession (for per-request / ephemeral cases)

    Each state exposes only the operations that are valid in that state, and transitions return the next state type.

  2. Model stateless mode explicitly

    • Instead of marking a stateful session as "Initialized" prematurely, model stateless HTTP as a dedicated StatelessSession type with a simpler lifecycle.
    • Make behavior differences clear in code and docs.
  3. Centralize resource cleanup

    • Ensure that all lifecycle paths (happy path, error, cancellation) lead through code that:
      • cancels outstanding tasks,
      • closes transports,
      • releases resources stored in AsyncExitStack.

Why this matters

  • Reliability: Fewer edge cases and surprise states where messages can be processed incorrectly.
  • Debuggability: Easier to reason about what can happen in each state.
  • Extensibility: Adding new lifecycle behavior (e.g., resuming sessions) becomes more manageable.

Acceptance criteria

  • Session lifecycle is represented via explicit types or a clearly defined state machine.
  • Stateless HTTP mode uses a dedicated path rather than setting "Initialized" as a hack.
  • All entry/exit paths of sessions ensure proper cleanup of transports and tasks.
  • Tests cover state transitions, including error cases and stateless/stat eful differences.

References

No response

Activity

  1. maxisbey commented on Dec 3, 2025

    @maxisbey
    Contributor

    Yea I actually like this, love to hear "state machine". For V2 of the Python SDK something like this could be really cool, but we'll have to pause on what exactly it'll look like until the upcoming transport changes have been a bit more finalised.

    Some relevant links for those discussions:

  2. added
    enhancementRequest for a new feature that's not currently supported
    v2Affects the v2 line (2.x on main)
    on Dec 3, 2025
  3. added
    P2Moderate issues affecting some users, edge cases, potentially valuable feature
    on Dec 9, 2025
  4. dgenio commented on Feb 28, 2026

    @dgenio
    Author

    Update: I've opened PR #2099 implementing Phase 1 of this proposal — expanding the InitializationState enum with Stateless, Closing, and Closed states, plus a centralized _VALID_TRANSITIONS table and _transition_state() validator.

    @maxisbey noted that the final shape should wait for the transport spec discussions to settle (linked in the comment above). The PR is designed as a non-breaking incremental step that doesn't lock in any specific transport model — additional states can be added to the transition table later.

    The PR applies cleanly to current main and includes 20 tests. Happy to iterate based on feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Moderate issues affecting some users, edge cases, potentially valuable featureenhancementRequest for a new feature that's not currently supportedv2Affects the v2 line (2.x on main)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions