change to fraction-based approach

next
Jonathan de Jong 2021-07-19 16:25:41 +02:00
parent 0f2dc9a239
commit 7e579f8d34
2 changed files with 16 additions and 21 deletions

View File

@ -53,8 +53,8 @@ pub struct Config {
sqlite_wal_clean_second_interval: u32, sqlite_wal_clean_second_interval: u32,
#[serde(default = "default_sqlite_wal_clean_second_timeout")] #[serde(default = "default_sqlite_wal_clean_second_timeout")]
sqlite_wal_clean_second_timeout: u32, sqlite_wal_clean_second_timeout: u32,
#[serde(default = "default_sqlite_spillover_reap_chunk")] #[serde(default = "default_sqlite_spillover_reap_fraction")]
sqlite_spillover_reap_chunk: u32, sqlite_spillover_reap_fraction: u32,
#[serde(default = "default_sqlite_spillover_reap_interval_secs")] #[serde(default = "default_sqlite_spillover_reap_interval_secs")]
sqlite_spillover_reap_interval_secs: u32, sqlite_spillover_reap_interval_secs: u32,
#[serde(default = "default_max_request_size")] #[serde(default = "default_max_request_size")]
@ -125,12 +125,12 @@ fn default_sqlite_wal_clean_second_timeout() -> u32 {
2 2
} }
fn default_sqlite_spillover_reap_chunk() -> u32 { fn default_sqlite_spillover_reap_fraction() -> u32 {
5 2
} }
fn default_sqlite_spillover_reap_interval_secs() -> u32 { fn default_sqlite_spillover_reap_interval_secs() -> u32 {
10 60
} }
fn default_max_request_size() -> u32 { fn default_max_request_size() -> u32 {
@ -558,10 +558,9 @@ impl Database {
#[cfg(feature = "sqlite")] #[cfg(feature = "sqlite")]
pub async fn start_spillover_reap_task(engine: Arc<Engine>, config: &Config) { pub async fn start_spillover_reap_task(engine: Arc<Engine>, config: &Config) {
let chunk_size = match config.sqlite_spillover_reap_chunk { use std::convert::TryInto;
0 => None, // zero means no chunking, reap everything
a @ _ => Some(a), let fraction_factor = config.sqlite_spillover_reap_fraction.max(1).try_into().unwrap(/* We just converted it to be at least 1 */);
};
let interval_secs = config.sqlite_spillover_reap_interval_secs as u64; let interval_secs = config.sqlite_spillover_reap_interval_secs as u64;
let weak = Arc::downgrade(&engine); let weak = Arc::downgrade(&engine);
@ -577,7 +576,7 @@ impl Database {
i.tick().await; i.tick().await;
if let Some(arc) = Weak::upgrade(&weak) { if let Some(arc) = Weak::upgrade(&weak) {
arc.reap_spillover(chunk_size); arc.reap_spillover_by_fraction(fraction_factor);
} else { } else {
break; break;
} }

View File

@ -9,6 +9,7 @@ use rusqlite::{params, Connection, DatabaseName::Main, OptionalExtension};
use std::{ use std::{
collections::BTreeMap, collections::BTreeMap,
future::Future, future::Future,
num::NonZeroU32,
ops::Deref, ops::Deref,
path::{Path, PathBuf}, path::{Path, PathBuf},
pin::Pin, pin::Pin,
@ -241,19 +242,14 @@ impl Engine {
.map_err(Into::into) .map_err(Into::into)
} }
// Reaps (at most) X amount of connections if `amount` is Some. // Reaps (at most) (.len() / `fraction`) (rounded down, min 1) connections.
// If none, reaps all currently idle connections. pub fn reap_spillover_by_fraction(&self, fraction: NonZeroU32) {
pub fn reap_spillover(&self, amount: Option<u32>) {
let mut reaped = 0; let mut reaped = 0;
if let Some(amount) = amount { let amount = ((self.pool.spills.1.len() as u32) / fraction).max(1);
for _ in 0..amount {
if self.pool.spills.try_take().is_some() { for _ in 0..amount {
reaped += 1; if self.pool.spills.try_take().is_some() {
}
}
} else {
while let Some(_) = self.pool.spills.try_take() {
reaped += 1; reaped += 1;
} }
} }