Description
In src/agent_setup.rs:680, apply_response_cache spawns a background cleanup task that runs in an infinite loop { interval.tick().await; ... } with no cancellation mechanism. There is no CancellationToken, shutdown_rx channel, or select! branch to terminate the loop.
In single-process CLI mode this is benign (process exit kills the task). However, in ACP multi-session scenarios where agent instances are created and dropped within a long-running process, the loop leaks across sessions and accumulates orphaned tasks.
Reproduction Steps
- Open
src/agent_setup.rs around line 680
- Observe:
tokio::spawn(async move { let mut interval = ...; loop { interval.tick().await; ... } })
- No shutdown signal is accepted; loop is not stored or tracked
Expected Behavior
The background cleanup task should accept a CancellationToken (or equivalent) and exit cleanly when the enclosing agent is dropped. At minimum the returned JoinHandle should be tracked so it can be aborted on session teardown.
Actual Behavior
The spawned task runs until process exit regardless of whether the ResponseCache it cleans is still in use. In ACP multi-session context this means one orphaned task per session over the lifetime of the process.
Environment
- Location:
src/agent_setup.rs:680 (inside apply_response_cache)
- Features: response cache enabled path only
- Impact: ACP multi-session scenarios; CLI single-session benign
Logs / Evidence
tokio::spawn(async move {
let mut interval = tokio::time::interval(std::time::Duration::from_hours(1));
interval.tick().await; // skip immediate first tick
loop {
interval.tick().await;
match cache_clone.cleanup(&embed_model).await { ... }
}
});
Description
In
src/agent_setup.rs:680,apply_response_cachespawns a background cleanup task that runs in an infiniteloop { interval.tick().await; ... }with no cancellation mechanism. There is noCancellationToken,shutdown_rxchannel, orselect!branch to terminate the loop.In single-process CLI mode this is benign (process exit kills the task). However, in ACP multi-session scenarios where agent instances are created and dropped within a long-running process, the loop leaks across sessions and accumulates orphaned tasks.
Reproduction Steps
src/agent_setup.rsaround line 680tokio::spawn(async move { let mut interval = ...; loop { interval.tick().await; ... } })Expected Behavior
The background cleanup task should accept a
CancellationToken(or equivalent) and exit cleanly when the enclosing agent is dropped. At minimum the returnedJoinHandleshould be tracked so it can be aborted on session teardown.Actual Behavior
The spawned task runs until process exit regardless of whether the
ResponseCacheit cleans is still in use. In ACP multi-session context this means one orphaned task per session over the lifetime of the process.Environment
src/agent_setup.rs:680(insideapply_response_cache)Logs / Evidence