From e0169e3dca5fa1e060e965720b3884951047edba Mon Sep 17 00:00:00 2001 From: dasha_uwu Date: Tue, 9 Sep 2025 18:12:21 +0500 Subject: [PATCH] presence refactor --- src/api/client/profile.rs | 26 ++++++++----------- src/api/client/read_marker.rs | 20 ++++++--------- src/api/client/sync/v3.rs | 21 ++++++--------- src/api/client/typing.rs | 12 ++++----- src/api/client/unstable.rs | 48 +++++++++++++++-------------------- src/service/presence/mod.rs | 38 +++++++++++++++++---------- 6 files changed, 77 insertions(+), 88 deletions(-) diff --git a/src/api/client/profile.rs b/src/api/client/profile.rs index 456bd4da..651baad9 100644 --- a/src/api/client/profile.rs +++ b/src/api/client/profile.rs @@ -46,13 +46,11 @@ pub(crate) async fn set_displayname_route( .update_displayname(&body.user_id, body.displayname.clone(), &all_joined_rooms) .await; - if services.config.allow_local_presence { - // Presence update - services - .presence - .ping_presence(&body.user_id, &PresenceState::Online) - .await?; - } + // Presence update + services + .presence + .maybe_ping_presence(&body.user_id, &PresenceState::Online) + .await?; Ok(set_display_name::v3::Response {}) } @@ -148,14 +146,12 @@ pub(crate) async fn set_avatar_url_route( ) .await; - if services.config.allow_local_presence { - // Presence update - services - .presence - .ping_presence(&body.user_id, &PresenceState::Online) - .await - .ok(); - } + // Presence update + services + .presence + .maybe_ping_presence(&body.user_id, &PresenceState::Online) + .await + .ok(); Ok(set_avatar_url::v3::Response {}) } diff --git a/src/api/client/read_marker.rs b/src/api/client/read_marker.rs index 2c9bf5ff..b57e9649 100644 --- a/src/api/client/read_marker.rs +++ b/src/api/client/read_marker.rs @@ -49,12 +49,10 @@ pub(crate) async fn set_read_marker_route( } if let Some(event) = &body.read_receipt { - if services.config.allow_local_presence { - services - .presence - .ping_presence(sender_user, &ruma::presence::PresenceState::Online) - .await?; - } + services + .presence + .maybe_ping_presence(sender_user, &ruma::presence::PresenceState::Online) + .await?; let receipt_content = BTreeMap::from_iter([( event.to_owned(), @@ -137,12 +135,10 @@ pub(crate) async fn create_receipt_route( .await?; }, | create_receipt::v3::ReceiptType::Read => { - if services.config.allow_local_presence { - services - .presence - .ping_presence(sender_user, &ruma::presence::PresenceState::Online) - .await?; - } + services + .presence + .maybe_ping_presence(sender_user, &ruma::presence::PresenceState::Online) + .await?; let receipt_content = BTreeMap::from_iter([( body.event_id.clone(), diff --git a/src/api/client/sync/v3.rs b/src/api/client/sync/v3.rs index cf482d46..8ff33a77 100644 --- a/src/api/client/sync/v3.rs +++ b/src/api/client/sync/v3.rs @@ -125,20 +125,15 @@ pub(crate) async fn sync_events_route( ) -> Result> { let (sender_user, sender_device) = body.sender(); - // Presence update - if services.config.allow_local_presence { - services - .presence - .ping_presence(sender_user, &body.body.set_presence) - .await - .log_err() - .ok(); + services + .presence + .maybe_ping_presence(sender_user, &body.body.set_presence) + .await + .log_err() + .ok(); - // Record user as actively syncing for push suppression heuristic. - if services.config.suppress_push_when_active { - services.presence.note_sync(sender_user).await; - } - } + // Record user as actively syncing for push suppression heuristic. + services.presence.note_sync(sender_user).await; let mut since = body .body diff --git a/src/api/client/typing.rs b/src/api/client/typing.rs index 0c948acc..ee12f817 100644 --- a/src/api/client/typing.rs +++ b/src/api/client/typing.rs @@ -28,7 +28,7 @@ pub(crate) async fn create_typing_event_route( match body.state { | Typing::Yes(duration) => { - let duration = utils::clamp( + let duration = Ord::clamp( duration .as_millis() .try_into() @@ -64,12 +64,10 @@ pub(crate) async fn create_typing_event_route( } // ping presence - if services.config.allow_local_presence { - services - .presence - .ping_presence(&body.user_id, &ruma::presence::PresenceState::Online) - .await?; - } + services + .presence + .maybe_ping_presence(&body.user_id, &ruma::presence::PresenceState::Online) + .await?; Ok(create_typing_event::v3::Response {}) } diff --git a/src/api/client/unstable.rs b/src/api/client/unstable.rs index 29541308..79c593c6 100644 --- a/src/api/client/unstable.rs +++ b/src/api/client/unstable.rs @@ -73,13 +73,11 @@ pub(crate) async fn delete_timezone_key_route( services.users.set_timezone(&body.user_id, None); - if services.config.allow_local_presence { - // Presence update - services - .presence - .ping_presence(&body.user_id, &PresenceState::Online) - .await?; - } + // Presence update + services + .presence + .maybe_ping_presence(&body.user_id, &PresenceState::Online) + .await?; Ok(delete_timezone_key::unstable::Response {}) } @@ -103,13 +101,11 @@ pub(crate) async fn set_timezone_key_route( .users .set_timezone(&body.user_id, body.tz.clone()); - if services.config.allow_local_presence { - // Presence update - services - .presence - .ping_presence(&body.user_id, &PresenceState::Online) - .await?; - } + // Presence update + services + .presence + .maybe_ping_presence(&body.user_id, &PresenceState::Online) + .await?; Ok(set_timezone_key::unstable::Response {}) } @@ -171,13 +167,11 @@ pub(crate) async fn set_profile_field_route( ); } - if services.config.allow_local_presence { - // Presence update - services - .presence - .ping_presence(&body.user_id, &PresenceState::Online) - .await?; - } + // Presence update + services + .presence + .maybe_ping_presence(&body.user_id, &PresenceState::Online) + .await?; Ok(set_profile_field::v3::Response {}) } @@ -227,13 +221,11 @@ pub(crate) async fn delete_profile_field_route( .set_profile_key(&body.user_id, body.field.as_str(), None); } - if services.config.allow_local_presence { - // Presence update - services - .presence - .ping_presence(&body.user_id, &PresenceState::Online) - .await?; - } + // Presence update + services + .presence + .maybe_ping_presence(&body.user_id, &PresenceState::Online) + .await?; Ok(delete_profile_field::v3::Response {}) } diff --git a/src/service/presence/mod.rs b/src/service/presence/mod.rs index 8eba63b8..725ecb02 100644 --- a/src/service/presence/mod.rs +++ b/src/service/presence/mod.rs @@ -44,12 +44,10 @@ impl crate::Service for Service { async fn worker(self: Arc) -> Result { // reset dormant online/away statuses to offline, and set the server user as // online - if self.services.server.config.allow_local_presence && !self.services.db.is_read_only() { - self.unset_all_presence().await; - _ = self - .ping_presence(&self.services.globals.server_user, &PresenceState::Online) - .await; - } + self.unset_all_presence().await; + _ = self + .maybe_ping_presence(&self.services.globals.server_user, &PresenceState::Online) + .await; let receiver = self.timer_channel.1.clone(); @@ -74,11 +72,9 @@ impl crate::Service for Service { async fn interrupt(&self) { // set the server user as offline - if self.services.server.config.allow_local_presence && !self.services.db.is_read_only() { - _ = self - .ping_presence(&self.services.globals.server_user, &PresenceState::Offline) - .await; - } + _ = self + .maybe_ping_presence(&self.services.globals.server_user, &PresenceState::Offline) + .await; let (timer_sender, _) = &self.timer_channel; if !timer_sender.is_closed() { @@ -93,6 +89,10 @@ impl Service { /// record that a user has just successfully completed a /sync (or /// equivalent activity) pub async fn note_sync(&self, user_id: &UserId) { + if !self.services.config.suppress_push_when_active { + return; + } + let now = tuwunel_core::utils::millis_since_unix_epoch(); self.last_sync_seen .write() @@ -120,9 +120,17 @@ impl Service { /// Pings the presence of the given user in the given room, setting the /// specified state. - pub async fn ping_presence(&self, user_id: &UserId, new_state: &PresenceState) -> Result { + pub async fn maybe_ping_presence( + &self, + user_id: &UserId, + new_state: &PresenceState, + ) -> Result { const REFRESH_TIMEOUT: u64 = 60 * 1000; + if !self.services.server.config.allow_local_presence || self.services.db.is_read_only() { + return Ok(()); + } + let last_presence = self.db.get_presence(user_id).await; let state_changed = match last_presence { | Err(_) => true, @@ -208,7 +216,11 @@ impl Service { } // Unset online/unavailable presence to offline on startup - pub async fn unset_all_presence(&self) { + async fn unset_all_presence(&self) { + if !self.services.server.config.allow_local_presence || self.services.db.is_read_only() { + return; + } + let _cork = self.services.db.cork(); for user_id in &self