// ---------- 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();
if !c.live { throw!(InstanceLockError::GameBeingDestroyed) }
InstanceGuard { c, gref: self.clone() }
}
+
+ fn lock_even_poisoned(&self) -> MutexGuard<InstanceContainer> {
+ match self.0.lock() {
+ Ok(g) => g,
+ Err(poison) => poison.into_inner(),
+ }
+ }
}
impl Instance {
// ---------- client expiry ----------
fn client_expire_old_clients() {
- fn lock_even_poisoned(gref: &InstanceRef) -> MutexGuard<InstanceContainer> {
- match gref.0.lock() {
- Ok(g) => g,
- Err(poison) => poison.into_inner(),
- }
- }
-
let mut expire = vec![];
let max_age = Instant::now() - MAX_CLIENT_INACTIVITY;
type Ret;
fn iter<'g>(&mut self, gref: &'g InstanceRef, max_age: Instant)
-> (MutexGuard<'g, InstanceContainer>, Option<Self::Ret>) {
- 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 }
}
}
+// ---------- 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";