From 473f390135029d99385175493c60a9534e80521a Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 17 Oct 2020 14:19:24 +0100 Subject: [PATCH] wip log expiry Signed-off-by: Ian Jackson --- src/gamestate.rs | 20 +++++++++++--------- src/global.rs | 43 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/gamestate.rs b/src/gamestate.rs index 3d69d2cb..77702d6c 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -285,16 +285,18 @@ impl PieceExt for T where T: Piece + ?Sized { // ---------- log expiry ========== impl GameState { - pub fn expire_old_logs(&mut self, cutoff: Timestamp) { - fn want_trim(gs: &GameState, cutoff: Timestamp) -> bool { - (||{ - let e = gs.log.get(1)?; - (e.1.when < cutoff).as_option() - })().is_some() - }; + pub fn want_expire_some_logs(&self, cutoff: Timestamp) -> bool { + (||{ + let e = self.log.get(1)?; + (e.1.when < cutoff).as_option() + })().is_some() + } + + pub fn do_expire_old_logs(&mut self, cutoff: Timestamp) { + let want_trim = |gs: &GameState| gs.want_expire_some_logs(cutoff); - if want_trim(self, cutoff) { - while want_trim(self, cutoff) { + if want_trim(self) { + while want_trim(self) { self.log.pop_front(); } let front = self.log.front_mut().unwrap(); diff --git a/src/global.rs b/src/global.rs index fd718f8b..c138be74 100644 --- a/src/global.rs +++ b/src/global.rs @@ -247,6 +247,13 @@ impl InstanceRef { if !c.live { throw!(InstanceLockError::GameBeingDestroyed) } InstanceGuard { c, gref: self.clone() } } + + fn lock_even_poisoned(&self) -> MutexGuard { + match self.0.lock() { + Ok(g) => g, + Err(poison) => poison.into_inner(), + } + } } impl Instance { @@ -1018,13 +1025,6 @@ pub fn game_flush_task() { // ---------- client expiry ---------- fn client_expire_old_clients() { - fn lock_even_poisoned(gref: &InstanceRef) -> MutexGuard { - match gref.0.lock() { - Ok(g) => g, - Err(poison) => poison.into_inner(), - } - } - let mut expire = vec![]; let max_age = Instant::now() - MAX_CLIENT_INACTIVITY; @@ -1032,7 +1032,7 @@ fn client_expire_old_clients() { type Ret; fn iter<'g>(&mut self, gref: &'g InstanceRef, max_age: Instant) -> (MutexGuard<'g, InstanceContainer>, Option) { - let c = lock_even_poisoned(gref); + let c = gref.lock_even_poisoned(); let ret = 'ret: loop { for (client, cl) in &c.g.clients { if cl.lastseen > max_age { continue } @@ -1086,6 +1086,33 @@ pub fn client_periodic_expiry() { } } +// ---------- log expiry ---------- + +fn global_expire_old_logs() { + let cutoff = Timestamp(Timestamp::now().0 - MAX_LOG_AGE.as_secs()); + + let mut want_expire = vec![]; + + let read = GLOBAL.games.read().unwrap(); + for gref in read.values() { + if gref.lock_even_poisoned().g.gs.want_expire_some_logs(cutoff) { + want_expire.push(gref.clone()) + } + } + drop(read); + + for gref in want_expire.drain(..) { + gref.lock_even_poisoned().g.gs.do_expire_old_logs(cutoff); + } +} + +pub fn logs_periodic_expiry() { + loop { + sleep(MAX_LOG_AGE/10); + global_expire_old_logs(); + } +} + // ========== server config ========== const DEFAULT_CONFIG_FILENAME : &str = "server.toml"; -- 2.30.2