-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add task to release unused db conns #1640
Changes from all commits
040688e
bf114e9
ba84d2b
a843cf7
8f4a11b
a81275a
c347572
2d271e5
2a14aca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,6 +99,13 @@ impl MysqlDbPool { | |
}) | ||
} | ||
|
||
/// Spawn a task to periodically evict idle connections. Calls wrapper sweeper fn | ||
/// to use pool.retain, retaining objects only if they are shorter in duration than | ||
/// defined max_idle. Noop for mysql impl. | ||
pub fn spawn_sweeper(&self, _interval: Duration) { | ||
sweeper() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can drop this and make |
||
} | ||
|
||
pub fn get_sync(&self) -> DbResult<MysqlDb> { | ||
Ok(MysqlDb::new( | ||
self.pool.get()?, | ||
|
@@ -110,6 +117,13 @@ impl MysqlDbPool { | |
} | ||
} | ||
|
||
/// Sweeper to retain only the objects specified within the closure. | ||
/// In this context, if a Spanner connection is unutilized, we want it | ||
/// to release the given connections. | ||
/// See: https://docs.rs/deadpool/latest/deadpool/managed/struct.Pool.html#method.retain | ||
/// Noop for mysql impl | ||
fn sweeper() {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, let's drop this. Less functions, less problems. |
||
|
||
#[async_trait] | ||
impl DbPool for MysqlDbPool { | ||
type Error = DbError; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
use std::{collections::HashMap, fmt, sync::Arc, time::Duration}; | ||
|
||
use actix_web::rt; | ||
use async_trait::async_trait; | ||
use syncserver_common::{BlockingThreadpool, Metrics}; | ||
use syncserver_db_common::{GetPoolState, PoolState}; | ||
|
@@ -49,7 +50,9 @@ impl SpannerDbPool { | |
let config = deadpool::managed::PoolConfig { | ||
max_size, | ||
timeouts, | ||
..Default::default() | ||
// Prefer LIFO to allow the sweeper task to evict least frequently | ||
// used connections. | ||
queue_mode: deadpool::managed::QueueMode::Lifo, | ||
}; | ||
let pool = deadpool::managed::Pool::builder(manager) | ||
.config(config) | ||
|
@@ -84,6 +87,30 @@ impl SpannerDbPool { | |
self.quota, | ||
)) | ||
} | ||
|
||
/// Spawn a task to periodically evict idle connections. Calls wrapper sweeper fn | ||
/// to use pool.retain, retaining objects only if they are shorter in duration than | ||
/// defined max_idle. | ||
pub fn spawn_sweeper(&self, interval: Duration) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you do move this to the |
||
let Some(max_idle) = self.pool.manager().settings.max_idle else { | ||
return; | ||
}; | ||
let pool = self.pool.clone(); | ||
rt::spawn(async move { | ||
loop { | ||
sweeper(&pool, Duration::from_secs(max_idle.into())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in general, prefer constructing something like this |
||
rt::time::sleep(interval).await; | ||
} | ||
}); | ||
} | ||
} | ||
|
||
/// Sweeper to retain only the objects specified within the closure. | ||
/// In this context, if a Spanner connection is unutilized, we want it | ||
/// to release the given connection. | ||
/// See: https://docs.rs/deadpool/latest/deadpool/managed/struct.Pool.html#method.retain | ||
fn sweeper(pool: &deadpool::managed::Pool<SpannerSessionManager>, max_idle: Duration) { | ||
pool.retain(|_, metrics| metrics.last_used() < max_idle); | ||
} | ||
|
||
#[async_trait] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is a function that all implementations of
DbPool
should perform, we should add it to theDbPool
trait (and move this to theimpl DbPool
block.I wonder if we should rename this to
spawn_maintenance
(spawn_janitor
?)While we don't need to sweep for pool connections for SQL libs, folk may want to do other maintenance things like run
vacuum
or the like.