fix arithmetic side-effects
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
52a561ff9e
commit
7397064edd
25 changed files with 139 additions and 114 deletions
|
@ -3,7 +3,7 @@ mod data;
|
|||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use conduit::{debug, error, utils, Error, Result};
|
||||
use conduit::{checked, debug, error, utils, Error, Result};
|
||||
use data::Data;
|
||||
use futures_util::{stream::FuturesUnordered, StreamExt};
|
||||
use ruma::{
|
||||
|
@ -79,12 +79,16 @@ pub struct Service {
|
|||
timer_receiver: Mutex<loole::Receiver<(OwnedUserId, Duration)>>,
|
||||
handler_join: Mutex<Option<JoinHandle<()>>>,
|
||||
timeout_remote_users: bool,
|
||||
idle_timeout: u64,
|
||||
offline_timeout: u64,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl crate::Service for Service {
|
||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
let config = &args.server.config;
|
||||
let idle_timeout_s = config.presence_idle_timeout_s;
|
||||
let offline_timeout_s = config.presence_offline_timeout_s;
|
||||
let (timer_sender, timer_receiver) = loole::unbounded();
|
||||
Ok(Arc::new(Self {
|
||||
db: Data::new(args.db),
|
||||
|
@ -92,6 +96,8 @@ impl crate::Service for Service {
|
|||
timer_receiver: Mutex::new(timer_receiver),
|
||||
handler_join: Mutex::new(None),
|
||||
timeout_remote_users: config.presence_timeout_remote_users,
|
||||
idle_timeout: checked!(idle_timeout_s * 1_000)?,
|
||||
offline_timeout: checked!(offline_timeout_s * 1_000)?,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -219,7 +225,7 @@ impl Service {
|
|||
loop {
|
||||
debug_assert!(!receiver.is_closed(), "channel error");
|
||||
tokio::select! {
|
||||
Some(user_id) = presence_timers.next() => process_presence_timer(&user_id)?,
|
||||
Some(user_id) = presence_timers.next() => self.process_presence_timer(&user_id)?,
|
||||
event = receiver.recv_async() => match event {
|
||||
Err(_e) => return Ok(()),
|
||||
Ok((user_id, timeout)) => {
|
||||
|
@ -230,6 +236,36 @@ impl Service {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn process_presence_timer(&self, user_id: &OwnedUserId) -> Result<()> {
|
||||
let mut presence_state = PresenceState::Offline;
|
||||
let mut last_active_ago = None;
|
||||
let mut status_msg = None;
|
||||
|
||||
let presence_event = self.get_presence(user_id)?;
|
||||
|
||||
if let Some(presence_event) = presence_event {
|
||||
presence_state = presence_event.content.presence;
|
||||
last_active_ago = presence_event.content.last_active_ago;
|
||||
status_msg = presence_event.content.status_msg;
|
||||
}
|
||||
|
||||
let new_state = match (&presence_state, last_active_ago.map(u64::from)) {
|
||||
(PresenceState::Online, Some(ago)) if ago >= self.idle_timeout => Some(PresenceState::Unavailable),
|
||||
(PresenceState::Unavailable, Some(ago)) if ago >= self.offline_timeout => Some(PresenceState::Offline),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
debug!(
|
||||
"Processed presence timer for user '{user_id}': Old state = {presence_state}, New state = {new_state:?}"
|
||||
);
|
||||
|
||||
if let Some(new_state) = new_state {
|
||||
self.set_presence(user_id, &new_state, Some(false), last_active_ago, status_msg)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn presence_timer(user_id: OwnedUserId, timeout: Duration) -> OwnedUserId {
|
||||
|
@ -237,36 +273,3 @@ async fn presence_timer(user_id: OwnedUserId, timeout: Duration) -> OwnedUserId
|
|||
|
||||
user_id
|
||||
}
|
||||
|
||||
fn process_presence_timer(user_id: &OwnedUserId) -> Result<()> {
|
||||
let idle_timeout = services().globals.config.presence_idle_timeout_s * 1_000;
|
||||
let offline_timeout = services().globals.config.presence_offline_timeout_s * 1_000;
|
||||
|
||||
let mut presence_state = PresenceState::Offline;
|
||||
let mut last_active_ago = None;
|
||||
let mut status_msg = None;
|
||||
|
||||
let presence_event = services().presence.get_presence(user_id)?;
|
||||
|
||||
if let Some(presence_event) = presence_event {
|
||||
presence_state = presence_event.content.presence;
|
||||
last_active_ago = presence_event.content.last_active_ago;
|
||||
status_msg = presence_event.content.status_msg;
|
||||
}
|
||||
|
||||
let new_state = match (&presence_state, last_active_ago.map(u64::from)) {
|
||||
(PresenceState::Online, Some(ago)) if ago >= idle_timeout => Some(PresenceState::Unavailable),
|
||||
(PresenceState::Unavailable, Some(ago)) if ago >= offline_timeout => Some(PresenceState::Offline),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
debug!("Processed presence timer for user '{user_id}': Old state = {presence_state}, New state = {new_state:?}");
|
||||
|
||||
if let Some(new_state) = new_state {
|
||||
services()
|
||||
.presence
|
||||
.set_presence(user_id, &new_state, Some(false), last_active_ago, status_msg)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue