Skip to content

Revisit single-use semantics of StreamableHTTPSessionManager.run() #1692

Closed as not planned

Description

@dgenio

Description

Summary

StreamableHTTPSessionManager currently enforces that run() can only be called once per instance. This is documented but not explained, and it complicates:

  • testing (each test must construct a new manager), and
  • any scenario that might want to reuse the manager for restarts.

It would be useful to either:

  • make run() safely reusable, or
  • codify and enforce single-use semantics in a clearer way.

Problems

  • Testing: Requiring a new manager instance for each run increases boilerplate and can hide lifecycle issues.
  • Unclear constraints: Users have to discover via runtime errors that run() is single-use, without an obvious reason.
  • Lifecycle complexity: The single-use constraint is a hint that some internal state (task groups, resource stacks) is not being fully reset.

Proposal

  1. Investigate why single-use is required

    • Document what internal state is left behind after run() completes (e.g., background tasks, queues).
    • Determine whether these can be safely reset at the start of the next run().
  2. Either: make run() reusable...

    • Reset internal state (task groups, lists of tasks, queues) before each run().
    • Ensure proper cleanup in finally blocks so the manager returns to a clean state.
  3. ...or explicitly codify single-use semantics

    • If reuse is fundamentally unsafe, consider:
      • modelling the manager as a consumable object (e.g., via documentation and type hints),
      • or returning a token/handle that marks the manager as “exhausted” after run().

Why this matters

  • Developer experience: Easier to write tests that exercise multiple lifecycles.
  • Robustness: Cleaning up state between runs reduces the risk of hidden leaks or race conditions.
  • Clarity: Either outcome (reusable or explicitly consumable) is better than a hidden constraint.

Acceptance criteria

  • The rationale for single-use semantics is documented (if they remain).
  • Either:
    • run() can be safely called multiple times on the same instance, or
    • Single-use semantics are enforced and clearly documented.
  • Tests cover repeated calls to run() and confirm expected behavior.

References

No response

Activity

  1. added
    enhancementRequest for a new feature that's not currently supported
    needs confirmationNeeds confirmation that the PR is actually required or needed.
    on Dec 3, 2025
  2. dgenio commented on Apr 9, 2026

    @dgenio
    Author

    Pinging to check if there's any appetite for resolving this. I'm happy to open a PR.

    Looking at the current implementation in streamable_http_manager.py, run() sets self._has_started = True and never resets it, so any subsequent call unconditionally raises a RuntimeError. The fix would be relatively small in either direction.

    Before investing the effort I'd like alignment on the preferred approach:

    1. Make run() reusable — reinitialize state (_server_instances, _task_group) at the start of each run() call and ensure the finally block leaves things in a clean state. This would be a small change and would directly improve testability.
    2. Explicitly codify single-use — if reuse is fundamentally unsafe (e.g. due to anyio Lock objects not being safely recreatable after a task group is cancelled), keep the guard but raise a more descriptive error and document the rationale clearly.

    Is there a preferred direction? Or is there a technical reason why reuse is intentionally unsafe that I may have missed?

  3. maxisbey commented on Aug 10, 2026

    @maxisbey
    Contributor

    Thanks for the report. Closing this as part of a wider backlog cleanup following the v2 launch. If it's still relevant, feel free to reopen.

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

    enhancementRequest for a new feature that's not currently supportedneeds confirmationNeeds confirmation that the PR is actually required or needed.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions