7

I want to poll an async function:

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    some_function().await;
}

I am currently activating all features:

tokio = { version = "1.4.0", features = ["full"] }

which of those are necessary?

full = [
  "fs",
  "io-util",
  "io-std",
  "macros",
  "net",
  "parking_lot",
  "process",
  "rt",
  "rt-multi-thread",
  "signal",
  "sync",
  "time",
]
kmdreko
  • 42,554
  • 6
  • 57
  • 106
Gatonito
  • 1,662
  • 5
  • 26
  • 55

1 Answers1

16

To enable polling a future with Tokio, you need a Runtime.

This is supported on crate feature rt only.

[dependencies]
tokio = { version = "1.4.0", features = ["rt"] }
fn main() -> Result<(), Box<dyn std::error::Error>> {
    tokio::runtime::Builder::new_current_thread()
        .build()
        .unwrap()
        .block_on(some_function())
}

async fn some_function() -> Result<(), Box<dyn std::error::Error>> {
    Ok(())
}

If you want to use the tokio::main macro:

This is supported on crate features rt and macros only.

[dependencies]
tokio = { version = "1.4.0", features = ["rt", "macros"] }
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    some_function().await
}

async fn some_function() -> Result<(), Box<dyn std::error::Error>> {
    Ok(())
}

If you want the exact syntax you've specified (which is not the "smallest feature set to enable polling a future with Tokio"), then the runtime error guides you:

The default runtime flavor is multi_thread, but the rt-multi-thread feature is disabled.

[dependencies]
tokio = { version = "1.4.0", features = ["rt", "rt-multi-thread", "macros"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    some_function().await
}

async fn some_function() -> Result<(), Box<dyn std::error::Error>> {
    Ok(())
}

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • thanks. I tried that before and I thought it wasn't possible because I got ``main` function is not allowed to be `async``. Is it possible to import one more thing just to make `#[tokio::main]` work? – Gatonito Apr 06 '21 at 02:48
  • 2
    @Gatonito To use the `tokio::main` attribute you need the `"macros"` feature, and the default runtime is multithreaded so you'll want `"rt-multi-thread"` instead of `"rt"`. – kmdreko Apr 06 '21 at 04:45
  • Could you add an example on how to keep `fn main` non async? I'm aware of `block_on` but I'm curious if there's a way to do like `std::thread::spawn` for an async-fn and poll it to be finished/join it without `await`. I'm make a DLL and I can't have `async` exported functions for C FFI reasons. – Brandon Ros Jun 05 '22 at 21:14
  • @BrandonRos the examples here are just that. While the source code says `async fn main`, the `#[tokio::main]` procedural macro rewrites that to `fn main`. – Shepmaster Jun 21 '22 at 17:04