rustrust-dieselr2d2

Imlementing connection pooling in a rust/diesel app with r2d2


I am trying to implement connection pooling in a rust/diesel/rocket application. I am not sure how to ensure the content of the establish_pooled_connection() method is invoked only once, so as to prepare the connection pool.

Here is my code.

from lib.rs:

pub fn establish_pooled_connection() -> PooledConnection<ConnectionManager<PgConnection>> {
    dotenv().ok();

    let database_url = env::var("DB_URL")
        .expect("DATABASE_URL must be set");

    let manager = ConnectionManager::<PgConnection>::new(&database_url);
    let pool = r2d2::Pool::builder().build(manager).expect("Failed to create pool.");
    let conn = pool.clone().get().unwrap();
    return conn;
}

Here I use the above method in main.rs:

#[get("/", format = "json")]
fn find_all() -> Json<Vec<Person>> {
    let connection = establish_pooled_connection();

    let all: QueryResult<Vec<Person>> = person::table().get_results(&connection);
    ...

The issue here is that each get method (e.g. above) calls the establish_pooled_connection() and everything is re-instantiated...

I come from the java world where dependency injection allows us to avoid re-instantiation.

What would be a proper way to implement connection pooling in an rust/diesel app?


Solution

  • You wouldn't create a new connection in every handler, but rather use some state-sharing mechanisms of your framework.

    See here for the guide on how to use state in rocket, that'll be a good starting point.