Reputation: 40641
when running code like this:
use futures::executor;
...
pub fn store_temporary_password(email: &str, password: &str) -> Result<(), Box<dyn Error>> {
let client = DynamoDbClient::new(Region::ApSoutheast2);
...
let future = client.put_item(input);
executor::block_on(future)?; <- crashes here
Ok(())
}
I get the error:
thread '<unnamed>' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime
My main has the tokio annotation as it should:
#[tokio::main]
async fn main() {
...
My cargo.toml looks like:
[dependencies]
...
futures = { version="0", features=["executor"] }
tokio = "1"
My cargo.lock shows that i only have 1 version of both futures and tokio ("1.2.0" and "0.3.12" respectively).
This exhausts the explanations I found elsewhere for this problem. Any ideas? Thanks.
Upvotes: 7
Views: 8898
Reputation: 13568
You have to enter the tokio runtime context before calling block_on
:
let handle = tokio::runtime::Handle::current();
handle.enter();
executor::block_on(future)?;
Note that your code is violating the rule that async functions should never spend a long time without reaching a .await
. Ideally, store_temporary_password
should be marked as async
to avoid blocking the current thread:
pub async fn store_temporary_password(email: &str, password: &str) -> Result<(), Box<dyn Error>> {
...
let future = client.put_item(input);
future.await?;
Ok(())
}
If that is not an option, you should wrap any calls to store_temporary_password
in tokio::spawn_blocking
to run the blocking operation on a separate threadpool.
Upvotes: 6