From 384dae58d8986f9159b53d0b0c06c225fd4fd42a Mon Sep 17 00:00:00 2001 From: Yang Xiufeng Date: Fri, 19 Sep 2025 18:02:03 +0800 Subject: [PATCH] feat: /v1/status include last_query_request_at. --- .../src/servers/admin/v1/instance_status.rs | 3 +++ .../servers/http/v1/http_query_handlers.rs | 3 +++ src/query/service/src/sessions/session_mgr.rs | 19 +++++++++++++++++++ .../src/sessions/session_mgr_status.rs | 2 ++ 4 files changed, 27 insertions(+) diff --git a/src/query/service/src/servers/admin/v1/instance_status.rs b/src/query/service/src/servers/admin/v1/instance_status.rs index 9dda38fe2e130..f8a1f8fefd69f 100644 --- a/src/query/service/src/servers/admin/v1/instance_status.rs +++ b/src/query/service/src/servers/admin/v1/instance_status.rs @@ -40,6 +40,8 @@ pub struct InstanceStatus { pub instance_started_at: u64, // the local timestamp, may be useful to avoid the clock drift issues pub instance_timestamp: u64, + // the timestamp on last valid request to /v1/query + pub last_query_request_at: Option, } // lightweight way to get status @@ -59,6 +61,7 @@ pub async fn instance_status_handler() -> poem::Result { max_running_query_executed_secs: status.max_running_query_executed_secs, instance_started_at: unix_timestamp_secs(status.instance_started_at), instance_timestamp: unix_timestamp_secs(SystemTime::now()), + last_query_request_at: status.last_query_request_at, }; Ok(Json(status)) } diff --git a/src/query/service/src/servers/http/v1/http_query_handlers.rs b/src/query/service/src/servers/http/v1/http_query_handlers.rs index ec1c3d7c2d11e..0c498caf6add6 100644 --- a/src/query/service/src/servers/http/v1/http_query_handlers.rs +++ b/src/query/service/src/servers/http/v1/http_query_handlers.rs @@ -93,6 +93,7 @@ use crate::servers::http::v1::HttpQueryManager; use crate::servers::http::v1::HttpSessionConf; use crate::servers::HttpHandlerKind; use crate::sessions::QueryAffect; +use crate::sessions::SessionManager; pub fn make_page_uri(query_id: &str, page_no: usize) -> String { format!("/v1/query/{}/page/{}", query_id, page_no) @@ -450,6 +451,7 @@ async fn query_page_handler( if next_is_final { query.wait_for_final() } + SessionManager::instance().new_query_request(); Ok(resp) } } @@ -499,6 +501,7 @@ pub(crate) async fn query_handler( client_session_id_info, mask_connection_info(&format!("{:?}", req)) ); + SessionManager::instance().new_query_request(); let sql = req.sql.clone(); match HttpQuery::try_create(ctx, req.clone()).await { diff --git a/src/query/service/src/sessions/session_mgr.rs b/src/query/service/src/sessions/session_mgr.rs index fa83f492dd690..a3e365b9b0919 100644 --- a/src/query/service/src/sessions/session_mgr.rs +++ b/src/query/service/src/sessions/session_mgr.rs @@ -16,10 +16,12 @@ use std::collections::HashMap; use std::future::Future; use std::ops::DerefMut; use std::sync::atomic::AtomicU32; +use std::sync::atomic::AtomicU64; use std::sync::atomic::Ordering; use std::sync::Arc; use std::sync::Weak; use std::time::Duration; +use std::time::SystemTime; use databend_common_base::base::tokio; use databend_common_base::base::GlobalInstance; @@ -57,6 +59,7 @@ pub struct SessionManager { // When typ is MySQL, insert into this map, key is id, val is MySQL connection id. pub(crate) mysql_conn_map: Arc, String>>>, pub(in crate::sessions) mysql_basic_conn_id: AtomicU32, + pub last_query_request_at: AtomicU64, } impl SessionManager { @@ -78,6 +81,7 @@ impl SessionManager { mysql_conn_map: Arc::new(RwLock::new(HashMap::with_capacity(max_sessions))), active_sessions: Arc::new(RwLock::new(HashMap::with_capacity(max_sessions))), metrics_collector: SessionManagerMetricsCollector::new(), + last_query_request_at: Default::default(), }); mgr.metrics_collector.attach_session_manager(mgr.clone()); mgr @@ -332,6 +336,13 @@ impl SessionManager { status_t.running_queries_count = running_queries_count; status_t.active_sessions_count = active_sessions_count; status_t.max_running_query_executed_secs = max_running_query_executed_secs; + + let last_query_request_at = self.last_query_request_at.load(Ordering::Acquire); + status_t.last_query_request_at = if last_query_request_at == 0 { + None + } else { + Some(last_query_request_at) + }; status_t } @@ -485,4 +496,12 @@ impl SessionManager { } Ok(all_temp_tables) } + + pub fn new_query_request(&self) { + let now = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("Time went backwards") + .as_secs(); + self.last_query_request_at.store(now, Ordering::Relaxed); + } } diff --git a/src/query/service/src/sessions/session_mgr_status.rs b/src/query/service/src/sessions/session_mgr_status.rs index 2db67041972af..dc0cd55bbd32f 100644 --- a/src/query/service/src/sessions/session_mgr_status.rs +++ b/src/query/service/src/sessions/session_mgr_status.rs @@ -22,6 +22,7 @@ pub struct SessionManagerStatus { pub last_query_started_at: Option, pub last_query_finished_at: Option, pub instance_started_at: SystemTime, + pub last_query_request_at: Option, } impl SessionManagerStatus { @@ -47,6 +48,7 @@ impl Default for SessionManagerStatus { last_query_started_at: None, last_query_finished_at: None, instance_started_at: SystemTime::now(), + last_query_request_at: None, } } }