things3_cli/mcp/middleware/
performance.rs1use super::{McpMiddleware, MiddlewareContext, MiddlewareResult};
4use crate::mcp::{CallToolRequest, CallToolResult, McpResult};
5use std::time::Duration;
6
7pub struct PerformanceMiddleware {
8 slow_request_threshold: Duration,
9}
10
11impl PerformanceMiddleware {
12 #[must_use]
14 pub fn new(slow_request_threshold: Duration) -> Self {
15 Self {
16 slow_request_threshold,
17 }
18 }
19
20 #[must_use]
22 pub fn create_default() -> Self {
23 Self::new(Duration::from_secs(1))
24 }
25
26 #[must_use]
28 pub fn with_threshold(threshold: Duration) -> Self {
29 Self::new(threshold)
30 }
31}
32
33#[async_trait::async_trait]
34impl McpMiddleware for PerformanceMiddleware {
35 fn name(&self) -> &'static str {
36 "performance"
37 }
38
39 fn priority(&self) -> i32 {
40 200 }
42
43 async fn after_request(
44 &self,
45 request: &CallToolRequest,
46 _response: &mut CallToolResult,
47 context: &mut MiddlewareContext,
48 ) -> McpResult<MiddlewareResult> {
49 let elapsed = context.elapsed();
50
51 context.set_metadata(
53 "duration_ms".to_string(),
54 serde_json::Value::Number(serde_json::Number::from(
55 u64::try_from(elapsed.as_millis()).unwrap_or(u64::MAX),
56 )),
57 );
58
59 context.set_metadata(
60 "is_slow".to_string(),
61 serde_json::Value::Bool(elapsed > self.slow_request_threshold),
62 );
63
64 if elapsed > self.slow_request_threshold {
66 println!(
67 "[PERF] Slow request detected: {} took {:?} (threshold: {:?})",
68 request.name, elapsed, self.slow_request_threshold
69 );
70 }
71
72 Ok(MiddlewareResult::Continue)
73 }
74}