diff --git a/src/database.rs b/src/database.rs index 6900088..c198f0e 100644 --- a/src/database.rs +++ b/src/database.rs @@ -967,17 +967,31 @@ impl Database { #[tracing::instrument(skip(db))] pub async fn start_watcher_prune_task(db: Arc>) { use std::time::Duration; - use tokio::time::interval; + use tokio::time::sleep; tokio::spawn(async move { - let mut i = interval(Duration::from_secs(60)); + let mut interval: usize = 15; + + const MAX_PRUNE_INTERVAL_SECS: usize = 60; loop { - i.tick().await; + sleep(Duration::from_secs(interval)).await; + + let mut pruned = false; for table in db.read().await._db.tables.read().values() { if let Some(table) = table.upgrade() { - table.prune_dead_watchers(); + pruned |= table.prune_dead_watchers(); + } + } + + if pruned { + if interval > 1 { + interval /= 2; + } + } else { + if interval < MAX_PRUNE_INTERVAL_SECS { + interval += 1; } } } diff --git a/src/database/abstraction/sqlite.rs b/src/database/abstraction/sqlite.rs index 06a8673..2848ab6 100644 --- a/src/database/abstraction/sqlite.rs +++ b/src/database/abstraction/sqlite.rs @@ -422,7 +422,7 @@ impl Tree for SqliteTable { } impl SqliteTable { - pub fn prune_dead_watchers(&self) { + pub fn prune_dead_watchers(&self) -> bool { let watchers = self.watchers.read(); let mut interesting = Vec::new(); for (key, (tx, _)) in watchers.iter() { @@ -450,7 +450,11 @@ impl SqliteTable { } } - debug!("Cleared {} dead watchers.", cleared) + debug!("Cleared {} dead watchers.", cleared); + + return cleared != 0; } + + false } }