From 736a9622571b6f992b61032bb7ff547e2c02311c Mon Sep 17 00:00:00 2001 From: h7x4 Date: Tue, 23 Jun 2026 17:09:17 +0900 Subject: [PATCH] rwhod: filter idle users and down hosts serverside --- src/bin/ruptime.rs | 2 +- src/bin/rwho.rs | 4 --- src/server/varlink_api.rs | 64 ++++++++++++++++++++++++--------------- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/bin/ruptime.rs b/src/bin/ruptime.rs index 43788c0..1e84ac0 100644 --- a/src/bin/ruptime.rs +++ b/src/bin/ruptime.rs @@ -67,7 +67,7 @@ async fn main() -> anyhow::Result<()> { .expect("Failed to connect to rwhod server"); let mut reply = conn - .ruptime() + .ruptime(args.all) .await .context("Failed to send rwho request")? .map_err(|e| anyhow::anyhow!("Server returned an error for rwho request: {:?}", e))?; diff --git a/src/bin/rwho.rs b/src/bin/rwho.rs index dd68fd1..0bec362 100644 --- a/src/bin/rwho.rs +++ b/src/bin/rwho.rs @@ -52,10 +52,6 @@ async fn main() -> anyhow::Result<()> { .context("Failed to send rwho request")? .map_err(|e| anyhow::anyhow!("Server returned an error for rwho request: {:?}", e))?; - if !args.all { - reply.retain(|(_, user)| user.idle_time.num_minutes() <= 11); - } - reply.sort_by(|(host, user), (host2, user2)| { user.user_id .cmp(&user2.user_id) diff --git a/src/server/varlink_api.rs b/src/server/varlink_api.rs index c984dfc..d336478 100644 --- a/src/server/varlink_api.rs +++ b/src/server/varlink_api.rs @@ -25,6 +25,7 @@ pub trait VarlinkRwhodClientProxy { async fn ruptime( &mut self, + all: bool, ) -> zlink::Result>; } @@ -38,7 +39,10 @@ pub enum VarlinkRwhodClientRequest { }, #[serde(rename = "no.ntnu.pvv.roowho2.rwhod.Ruptime")] - Ruptime, + Ruptime { + /// Count all users, even those that have been idle for a long time. + all: bool, + }, } #[derive(Debug, Clone, PartialEq, Serialize)] @@ -140,29 +144,35 @@ impl VarlinkRoowhoo2ClientServer { } impl VarlinkRoowhoo2ClientServer { - // TODO: handle 'all' parameter - async fn handle_rwho_request(&self, _all: bool) -> VarlinkRwhoResponse { - tracing::debug!(all = _all, "Handling Rwho request"); + async fn handle_rwho_request(&self, all: bool) -> VarlinkRwhoResponse { + tracing::debug!(all, "Handling Rwho request"); let store = self.whod_status_store.read().await; let mut all_user_entries = Vec::with_capacity(store.len()); for status_update in store.values() { - all_user_entries.extend_from_slice( - &status_update + all_user_entries.extend( + status_update .users .iter() - .map(|user| (status_update.hostname.clone(), user.clone())) - .collect::>(), + .filter(|user| all || user.idle_time < chrono::Duration::hours(1)) + .cloned() + .map(|user| (status_update.hostname.clone(), user)), ); } all_user_entries } - async fn handle_ruptime_request(&self) -> VarlinkRuptimeResponse { - tracing::debug!("Handling Ruptime request"); + async fn handle_ruptime_request(&self, all: bool) -> VarlinkRuptimeResponse { + tracing::debug!(all, "Handling Ruptime request"); let store = self.whod_status_store.read().await; - store.values().cloned().collect() + store + .values() + .filter(|status_update| { + all || chrono::Utc::now() - status_update.sendtime < chrono::Duration::hours(1) + }) + .cloned() + .collect() } async fn handle_finger_request( @@ -263,20 +273,24 @@ impl zlink::Service for VarlinkRoowhoo2ClientServer { Default::default(), ) } - VarlinkMethod::Rwhod(VarlinkRwhodClientRequest::Ruptime) => { - let result = - match timeout(Duration::from_secs(2), self.handle_ruptime_request()).await { - Ok(response) => response, - Err(_) => { - tracing::error!("Ruptime request timed out after 2 seconds"); - return ( - MethodReply::Error(VarlinkReplyError::Rwhod( - VarlinkRwhodClientError::TimedOut, - )), - Default::default(), - ); - } - }; + VarlinkMethod::Rwhod(VarlinkRwhodClientRequest::Ruptime { all }) => { + let result = match timeout( + Duration::from_secs(2), + self.handle_ruptime_request(*all), + ) + .await + { + Ok(response) => response, + Err(_) => { + tracing::error!("Ruptime request timed out after 2 seconds"); + return ( + MethodReply::Error(VarlinkReplyError::Rwhod( + VarlinkRwhodClientError::TimedOut, + )), + Default::default(), + ); + } + }; ( MethodReply::Single(Some(VarlinkReply::Rwhod(