Skip to content

Conversation

@mdworsky
Copy link
Collaborator

Summary

  • Fix cancel scope errors when using the SDK with trio by implementing the "owner task pattern"
  • Ensure inner task groups are properly managed by a single task, satisfying trio's strict cancel scope ownership requirements
  • Add 13 new tests covering the owner task pattern with both asyncio and trio backends

Problem

The SDK was manually calling __aenter__ and __aexit__ on anyio task groups, which violates trio's requirement that cancel scopes must be exited by the same task that entered them. This caused errors like:

RuntimeError: Attempted to exit cancel scope in a different task than it was entered in

Solution

Implement the owner task pattern: a dedicated task owns the inner task group for its entire lifetime using proper async with semantics. The outer code communicates with this owner task via events:

  • start() spawns the owner task and waits for _owner_started_event
  • close() sets _owner_stop_event, signaling the owner to cancel and exit cleanly

This ensures the inner task group (which does the actual message reading) is always entered and exited by the same task.

Test plan

  • All 130 tests pass (117 existing + 13 new)
  • New tests verify owner task lifecycle with asyncio backend
  • New tests verify owner task lifecycle with trio backend
  • Concurrent operations work correctly with both backends

🤖 Generated with Claude Code

🏠 Remote-Dev: homespace
@mdworsky mdworsky marked this pull request as draft November 24, 2025 16:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants