1

I've been using once_cell to do a lot of work that only needs to be done once, and then persist as read-only global. This is nice because I don't have to pass these things around. I was wanting to know if something like this is permitted for db handles/pools?

static POOL: Pool<Postgres> = PgPoolOptions::new()
    .max_connections(5)
    .connect("postgres://postgres:password@localhost/test")
    .await
    .unwrap();

But alas, this doesn't work because of the .await,

error[E0744]: `.await` is not allowed in a `static`
  --> src/main.rs:10:31

And, if I try to wrap in once_cell, I get

static POOL = Lazy::new(|| sqlx_rt::block_on(
  PgPoolOptions::new()
      .max_connections(5)
      .connect("postgres://postgres:password@localhost/test")
      .await
) );

Is there anyway to do what I want here

Sebastián Palma
  • 32,692
  • 6
  • 40
  • 59
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
  • it would be possible to have static where each time you want access them you need to be in a async context but... I think the good way would be to make your singleton yourself by calling the init yourself in a async fn main – Stargateur Apr 22 '21 at 06:07

1 Answers1

4

Tokio OnceCell (added in Tokio 1.5.0 released April 12, 2021)

Tokio now provides an async OnceCell, tokio::sync::OnceCell! You can use the Tokio OnceCell for async code.


Using the once_cell crate (early 2021 answer)

The once_cell crate does not currently provide an async API. Instead, you can initialize the static from your main function:

static POOL: OnceCell<String> = OnceCell::new();

#[rt::main]
async fn main() {
    let pg_pool = PgPoolOptions::new()
        .max_connections(5)
        .connect("postgres://postgres:password@localhost/test")
        .await
        .unwrap();
    POOL.set(pg_pool).unwrap();
}
Colin D Bennett
  • 11,294
  • 5
  • 49
  • 66
Ibraheem Ahmed
  • 11,652
  • 2
  • 48
  • 54
  • UPDATE: Tokio now provides an async OnceCell! Yay! https://docs.rs/tokio/1.27.0/tokio/sync/struct.OnceCell.html (It was actually being developed and prepped for release right around the time this answer was posted in April 2021.) – Colin D Bennett Apr 12 '23 at 18:02