MCPcopy Create free account
hub / github.com/AI45Lab/Code / disconnect_idle

Method disconnect_idle

core/src/mcp/manager.rs:212–254  ·  view source on GitHub ↗

Disconnect every connected server whose last-used timestamp is older than `now - idle_threshold_ms`. Returns the names of servers that were disconnected. Servers without a recorded timestamp are treated as **infinitely idle** and disconnected. The disconnect call itself can fail per-server (e.g. transport already closed); those failures are warn-logged but never panic — the result vec still inclu

(&self, idle_threshold_ms: u64)

Source from the content-addressed store, hash-verified

210 /// [`call_tool`](Self::call_tool) on the same server name will
211 /// require an explicit `connect` to come back online.
212 pub async fn disconnect_idle(&self, idle_threshold_ms: u64) -> Vec<String> {
213 let cutoff = now_epoch_ms().saturating_sub(idle_threshold_ms);
214 // Snapshot candidates so we don't hold both locks across await.
215 let candidates: Vec<String> = {
216 let clients = self.clients.read().await;
217 let last_used = self.last_used_at_ms.read().await;
218 clients
219 .keys()
220 .filter(|name| match last_used.get(*name) {
221 Some(ts) => *ts < cutoff,
222 // No timestamp -> never used since connect; treat as
223 // infinitely idle.
224 None => true,
225 })
226 .cloned()
227 .collect()
228 };
229 let mut disconnected = Vec::with_capacity(candidates.len());
230 for name in candidates {
231 match self.disconnect(&name).await {
232 Ok(()) => disconnected.push(name),
233 Err(e) => tracing::warn!(
234 server = %name,
235 error = %e,
236 "MCP idle disconnect failed; entry already removed from registry"
237 ),
238 }
239 }
240 // Opportunistically purge orphan timestamps for servers that are no
241 // longer connected — `touch()` records a timestamp unconditionally
242 // (even for a never-connected name), and the candidate scan above
243 // only iterates `clients.keys()`, so without this sweep those
244 // orphan entries in `last_used_at_ms` would accumulate unbounded
245 // across the lifetime of a long-running manager.
246 {
247 let clients = self.clients.read().await;
248 self.last_used_at_ms
249 .write()
250 .await
251 .retain(|name, _| clients.contains_key(name));
252 }
253 disconnected
254 }
255
256 /// Get all registered server configurations
257 pub async fn all_configs(&self) -> Vec<McpServerConfig> {

Calls 5

disconnectMethod · 0.80
writeMethod · 0.80
now_epoch_msFunction · 0.70
getMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected