-1

I have the following function that connects to a database using sqlx):

async fn testConnect() -> anyhow::Result<PgPool> {
    delay_for(Duration::from_millis(3000)).await;
    let pool = PgPoolOptions::new()
        .max_connections(5)
        .connect(&"database_connection_string")
        .await?;

    Ok(pool)
}

And I run it on the tokio runtime:

let mut threaded_rt = runtime::Builder::new()
    .threaded_scheduler()
    .enable_all()
    .build()
    .unwrap();
threaded_rt.block_on(future::lazy(move |_| {
    let handle = tokio::spawn(testConnect());
    return handle;
}));

Any code after delay_for inside testConnect does not get executed. Why is this and how can I make both awaits run?

If I remove the delay_for line of code, the database connection code runs as expected.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Fachtna Simi
  • 437
  • 2
  • 13
  • how do you know ? Do you wait your task ? – Stargateur Jul 20 '20 at 14:15
  • It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Jul 20 '20 at 14:22
  • By the way, idiomatic Rust uses `snake_case` for variables, methods, macros, fields and modules; `UpperCamelCase` for types and enum variants; and `SCREAMING_SNAKE_CASE` for statics and constants. – Shepmaster Jul 20 '20 at 14:22
  • You might as well use `#[tokio::main]`. See [How do I synchronously return a value calculated in an asynchronous Future in stable Rust?](https://stackoverflow.com/q/52521201/155423). – Shepmaster Jul 20 '20 at 14:27

1 Answers1

1

I suspect that the following happens. This is analogue to starting a background worker thread and quit without joining it.

  • you spawn the task on tokio and return the handle
  • block_on drives the tokio reactor for a little while which is just enough for a normal connection, but not enough for the delay to expire
  • nothing drives the reactor anymore, so the result of the spawned task is just dropped and the program exits

If so, you can fix it simply by calling threaded_rt.block_on(testConnect()) directly, the spawn() part seems to be completely pointless.

Zólyomi István
  • 2,401
  • 17
  • 28