Closed inzanez closed 4 years ago
Great question! At the moment there aren't any plans to include that in the official API, because the general case is pretty easy to support without adding an extra surface. What has worked pretty well for me is adding a block of code that looks like this:
use lazy_static::*;
use r2d2::Pool;
use diesel::r2d2::ConnectionManager;
use diesel::pg::PgConnection;
use dotenv::dotenv;
use std::env;
lazy_static! {
static ref CONNECTION_POOL: Pool<ConnectionManager<PgConnection>> = {
dotenv().ok();
let database_url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set");
println!("Starting db pool at: {}", database_url);
let manager = ConnectionManager::new(database_url);
let pool = r2d2::Pool::builder()
.max_size(15)
.build(manager)
.unwrap();
pool
};
}
pub mod db {
use diesel::pg::PgConnection;
use diesel::r2d2::ConnectionManager;
use std::env;
use r2d2::PooledConnection;
use crate::util::CONNECTION_POOL;
pub fn establish_connection() -> PooledConnection<ConnectionManager<PgConnection>> {
let database_url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set");
CONNECTION_POOL.get()
.expect(&format!("Error connecting to {}", database_url))
}
}
That being said, I'm always to hear how adding/changing API surfaces would make lives easier!
@inzanez friendly ping!
How would you use this lazy_static!
approach if your database pool is async?
Forgive me, I'm still waking up, but do you have an example of an async database pool in which lazy_static
wouldn't work? It's much easier for me to think in code!
Forgive me, I'm still waking up ...
Same, so this might be a little rough!
I've been experimenting with SQLx which is fully async, even establishing the connection pool.
let pool = sqlx::PgPool::new(database_url).await.unwrap();
Trying something like the following doesn't work, as the async
block returns a future.
lazy_static! {
static ref POOL: sqlx::PgPool = async {
sqlx::PgPool::new(database_url).await.unwrap()
};
}
My async/await game is pretty rough (and I'm not great with Rust in general), so this was a pattern I wasn't sure how to resolve.
@kevlarr If you don't have an minimum idle set in your Pool configuration (which is the default.. so maybe we should just make Pool::new
not async), you can do:
sqlx::PgPool::new(database_url).now_or_never().unwrap()
now_or_never
comes from FutureExt
in the futures
project.
@mehcode Ah that's excellent - thank you!
State can now also be stored and shared at the app level thanks to #152
Are there plans to allow storing application state in some form? Like an R2D2 connection manager that can be used within routes to retrieve a database session?