From 6295ca135a467e825f0a5a6fbf93499c19a10e8b Mon Sep 17 00:00:00 2001 From: tototomate123 Date: Tue, 2 Sep 2025 17:16:41 +0200 Subject: [PATCH] feature marked as experimental and executed rustfmt --- src/api/client/sync/v3.rs | 3 ++- src/core/config/mod.rs | 7 +++---- src/service/presence/mod.rs | 12 ++++++++---- src/service/sending/sender.rs | 36 +++++++++++++++++++++++++++-------- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/api/client/sync/v3.rs b/src/api/client/sync/v3.rs index 33014b2e..9759c7cb 100644 --- a/src/api/client/sync/v3.rs +++ b/src/api/client/sync/v3.rs @@ -134,7 +134,8 @@ pub(crate) async fn sync_events_route( .log_err() .ok(); - // Record that this user was actively syncing now (for push suppression heuristic) + // Record that this user was actively syncing now (for push suppression + // heuristic) services.presence.note_sync(sender_user).await; } diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 5532a5b2..1a1035d9 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -1288,13 +1288,12 @@ pub struct Config { #[serde(default = "true_fn")] pub presence_timeout_remote_users: bool, - - /// Suppresses push notifications for users marked as active. + /// Suppresses push notifications for users marked as active. (Experimental) /// - /// when enabled, users with `Online` presence and recent activity + /// When enabled, users with `Online` presence and recent activity /// (based on presence state and sync activity) won’t receive push /// notifications, reducing duplicate alerts while they're active - /// elsewhere. + /// on another client. /// /// Disabled by default to preserve legacy behavior. #[serde(default)] diff --git a/src/service/presence/mod.rs b/src/service/presence/mod.rs index b564cd84..8eba63b8 100644 --- a/src/service/presence/mod.rs +++ b/src/service/presence/mod.rs @@ -2,13 +2,12 @@ mod data; mod presence; use std::{collections::HashMap, sync::Arc, time::Duration}; -use tokio::sync::RwLock; use async_trait::async_trait; use futures::{Stream, StreamExt, TryFutureExt, stream::FuturesUnordered}; use loole::{Receiver, Sender}; use ruma::{OwnedUserId, UInt, UserId, events::presence::PresenceEvent, presence::PresenceState}; -use tokio::time::sleep; +use tokio::{sync::RwLock, time::sleep}; use tuwunel_core::{Error, Result, checked, debug, debug_warn, error, result::LogErr, trace}; use self::{data::Data, presence::Presence}; @@ -91,10 +90,14 @@ impl crate::Service for Service { } impl Service { - /// record that a user has just successfully completed a /sync (or equivalent activity) + /// record that a user has just successfully completed a /sync (or + /// equivalent activity) pub async fn note_sync(&self, user_id: &UserId) { let now = tuwunel_core::utils::millis_since_unix_epoch(); - self.last_sync_seen.write().await.insert(user_id.to_owned(), now); + self.last_sync_seen + .write() + .await + .insert(user_id.to_owned(), now); } /// Returns milliseconds since last observed sync for user (if any) @@ -106,6 +109,7 @@ impl Service { .get(user_id) .map(|ts| now.saturating_sub(*ts)) } + /// Returns the latest presence event for the given user. pub async fn get_presence(&self, user_id: &UserId) -> Result { self.db diff --git a/src/service/sending/sender.rs b/src/service/sending/sender.rs index eb29fb81..656c0ede 100644 --- a/src/service/sending/sender.rs +++ b/src/service/sending/sender.rs @@ -19,13 +19,14 @@ use ruma::{ MilliSecondsSinceUnixEpoch, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, ServerName, UInt, api::{ - appservice::event::push_events::v1::EphemeralData, federation::transactions::{ + appservice::event::push_events::v1::EphemeralData, + federation::transactions::{ edu::{ DeviceListUpdateContent, Edu, PresenceContent, PresenceUpdate, ReceiptContent, ReceiptData, ReceiptMap, }, send_transaction_message, - } + }, }, device_id, events::{ @@ -833,21 +834,40 @@ impl Service { continue; } - // optional suppression: heuristic combining presence age and recent sync activity. - if self.services.server.config.suppress_push_when_active { - if let Ok(presence) = self.services.presence.get_presence(&user_id).await { - let is_online = presence.content.presence == ruma::presence::PresenceState::Online; + // optional suppression: heuristic combining presence age and recent sync + // activity. + if self + .services + .server + .config + .suppress_push_when_active + { + if let Ok(presence) = self + .services + .presence + .get_presence(&user_id) + .await + { + let is_online = + presence.content.presence == ruma::presence::PresenceState::Online; let presence_age_ms = presence .content .last_active_ago .map(u64::from) .unwrap_or(u64::MAX); - let sync_gap_ms = self.services.presence.last_sync_gap_ms(&user_id).await; + let sync_gap_ms = self + .services + .presence + .last_sync_gap_ms(&user_id) + .await; let considered_active = is_online && presence_age_ms < 65_000 && sync_gap_ms.is_some_and(|gap| gap < 32_000); if considered_active { - trace!(?user_id, presence_age_ms, sync_gap_ms, "suppressing push: active heuristic"); + trace!( + ?user_id, + presence_age_ms, sync_gap_ms, "suppressing push: active heuristic" + ); continue; } }