2

I'm using the recommended rocket_db_pools crate to create a database pool and attach it to Rocket e.g.

#[derive(Database)]
#[database("birthdays")]
struct DB(sqlx::SqlitePool);


// in main
rocket::build()
        .attach(DB::init())

I would like to access the same database pool outside of the context of Rocket. I'm attempting to spawn a separate tokio task that runs alongside Rocket and does some additional background work e.g.

async fn main() -> _ {
  rocket::tokio::spawn(async {
    // access DB pool here
  })

  rocket::build()
    // ...
}

Is there a way to initialize a sqlx::SqlitePool and easily provide it to both the background task and Rocket so I can still leverage the automatic #[derive(Database)] goodies that rocket_db_pools provides?

As a relative rust beginner I'm having a hard time reading through the traits and understanding if there is a way to do so that doesn't require doing it fully custom by creating a pool, writing my own impl FromRequest, etc.

josephmr
  • 51
  • 3

1 Answers1

3

I found an alternative based on the example from rocket_sync_db_pools which I adapted for the differences with rocket_db_pools.

It uses a fairing to get access to the Database after it has been initialized and then clones the wrapped SqlitePool to move into the task.

#[derive(Database)]
#[database("birthdays")]
struct DB(sqlx::SqlitePool);

// in main
rocket::build()
        .attach(DB::init())
        .attach(AdHoc::try_on_ignite("Background job", |rocket| async {
            let pool = match DB::fetch(&rocket) {
                Some(pool) => pool.0.clone(), // clone the wrapped pool
                None => return Err(rocket),
            };

            rocket::tokio::task::spawn(async move {
                loop {
                    if let Ok(mut conn) = pool.acquire().await {
                        let results = sqlx::query_as::<_, Birthday>(
                            "SELECT name, birthday, account_id FROM birthdays",
                        )
                        .fetch_all(&mut conn)
                        .await
                        .expect("query should succeed");
                        debug!("selected from birthdays: {:?}", results);
                    }
                    sleep(Duration::from_secs(10)).await;
                }
            });

            Ok(rocket)
        }))
josephmr
  • 51
  • 3