Skip to content

Commit

Permalink
Add documentation for long-lived Postgres pools
Browse files Browse the repository at this point in the history
  • Loading branch information
seanlinsley committed Sep 28, 2023
1 parent 884629f commit 8858328
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
45 changes: 45 additions & 0 deletions postgres/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,51 @@ async fn main() {
}
```

## Example for a long-lived process

```rust,no_run
pub static DB_POOL_SIZE: Lazy<usize> = Lazy::new(|| {
env::var("DB_POOL").map(|v| v.parse().unwrap()).unwrap_or(1)
});
pub static DB_POOL: Lazy<Arc<deadpool_postgres::Pool>> = Lazy::new(|| {
Arc::new(db_pool(&env::var("DB_URL").unwrap()))
});
fn db_pool(url: &str) -> deadpool_postgres::Pool {
let mut pg_config = tokio_postgres::Config::from_str(url).unwrap();
pg_config.options("-c timezone=UTC -c statement_timeout=120s");
pg_config.connect_timeout(Duration::from_secs(30));
pg_config.keepalives_idle(Duration::from_secs(5 * 60));
// Allow TLS connections but don't verify the certificate (not yet supported by tokio-postgres)
let mut ssl_builder = openssl::ssl::SslConnector::builder(openssl::ssl::SslMethod::tls()).unwrap();
ssl_builder.set_verify(openssl::ssl::SslVerifyMode::NONE);
let tls = postgres_openssl::MakeTlsConnector::new(ssl_builder.build());
let mgr_config = deadpool_postgres::ManagerConfig { recycling_method: deadpool_postgres::RecyclingMethod::Fast };
let mgr = deadpool_postgres::Manager::from_config(pg_config, tls, mgr_config);
deadpool_postgres::Pool::builder(mgr).max_size(*DB_POOL_SIZE).build().unwrap()
}
// your code calls DB_POOL.get().await? to get a database connection
```

Note that tokio-postgres has been known to leak memory, so it's good to drop old database connections periodically:

```rust,no_run
fn main() {
std::thread::spawn(|| drop_old_db_connections());
}
fn drop_old_db_connections() {
loop {
std::thread::sleep(std::time::Duration::from_secs(60));
DB_POOL.retain(|_, metrics| metrics.age().as_secs() < 120);
}
}
```

## Example with `config` and `dotenv` crate

```env
Expand Down
7 changes: 5 additions & 2 deletions src/managed/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,15 +501,18 @@ impl<M: Manager, W: From<Object<M>>> Pool<M, W> {
///
/// The following example starts a background task that
/// runs every 30 seconds and removes objects from the pool
/// that haven't been used for more than one minute.
/// that are more than one minute old.
///
/// Note that tokio-postgres has been known to leak memory,
/// so pruning old database connections is good practice.
///
/// ```rust,ignore
/// let interval = Duration::from_secs(30);
/// let max_age = Duration::from_secs(60);
/// tokio::spawn(async move {
/// loop {
/// tokio::time::sleep(interval).await;
/// pool.retain(|_, metrics| metrics.last_used() < max_age);
/// pool.retain(|_, metrics| metrics.age() < max_age);
/// }
/// });
/// ```
Expand Down

0 comments on commit 8858328

Please sign in to comment.