Skip to main content

Module lifecycle

Module lifecycle 

Source
Expand description

Channel-based MCP server lifecycle management.

The previous design attempted to put lifecycle timers (idle disconnect, keep-alive health checks) inside the same McpManagerInner that is guarded by a tokio::sync::Mutex. This caused a deadlock risk: an idle timer callback firing on a background task would need to re-acquire the mutex, while the agent thread might also be waiting for the callback.

To break this, lifecycle events are sent over an mpsc channel to a dedicated background task that owns the timer handles. The background task only holds a Weak<McpManager> (no reference cycles) and re-enters the manager through a public async method that acquires the mutex on its own — which can never deadlock with the agent thread because the agent thread is not waiting for the lifecycle task while holding the lock.

  [Agent task]                [Lifecycle task]            [McpManager]
       │                            │                          │
       │ call_tool()                │                           │
       ├─ lock(inner) ──────────────┼──────────────────────────► │
       │ do work                    │                           │
       ├─ unlock                    │                           │
       │                            │                           │
       │                            │ (idle timer fires)        │
       │                            ├─ Weak::upgrade() ───────► │
       │                            │ disconnect_server()       │
       │                            │   ├─ lock(inner) ───────► │
       │                            │   ├─ unlock              │
       │                            │                           │
       │ ← no contention: agent is not holding the lock when    │
       │   the lifecycle task tries to acquire it.              │

Enums§

LifecycleEvent
Lifecycle events sent from McpManager to the background task.

Functions§

channel
Create a new lifecycle event channel.
lifecycle_event_loop
The background task that owns all timer handles.

Type Aliases§

LifecycleRx
Receiver side of the lifecycle channel.
LifecycleTx
Sender side of the lifecycle channel.