7

When I try to use actix-web 3 and rusoto 0.46 together I get the following runtime error:

thread 'actix-rt:worker:0' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime', /Users/matt/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.2.0/src/runtime/blocking/pool.rs:85:33

Small reproducible:

use actix_web::{get, App, HttpResponse, HttpServer, Responder}; // 3
use rusoto_core::Region; // 0.46 
use rusoto_dynamodb::{DynamoDb, DynamoDbClient, ListTablesInput};
use std::default::Default;

#[get("/tables")]
async fn tables(_req_body: String) -> impl Responder {
    let client = DynamoDbClient::new(Region::default());
    let list_tables_input: ListTablesInput = Default::default();
    match client.list_tables(list_tables_input).await {
        Ok(_output) => HttpResponse::Ok().finish(),
        Err(_error) => HttpResponse::InternalServerError().finish(),
    }
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().service(tables))
        .bind("0.0.0.0:8080")?
        .run()
        .await
}

Accompanying Cargo file:

[package]
name = "hello_actix_rusoto"
version = "0.1.0"
authors = ["Matt Roberts <mattroberts297@users.noreply.github.com>"]
edition = "2018"

[dependencies]
rusoto_core = "0.46"
rusoto_dynamodb = "0.46"
actix-web = "3"

Here is a link to a very small GitHub repo with the full code and here is how to reproduce the error:

git clone git@github.com:mattroberts297/hello_actix_rusoto.git
cd hello_actix_rusoto
docker-compose up -d
AWS_REGION=local cargo run &
curl -v 'http://127.0.0.1:8080/tables'
Matt Roberts
  • 1,107
  • 10
  • 15

1 Answers1

12

rusoto v0.46 depends on tokio v1.0. actix-web v3 however, is still using tokio v0.2. The two versions are not backward compatible, hence the error message. To solve this, you can upgrade to a newer version of actix-web:

actix-web = "4.0.0-beta.8"

Or you can use the tokio-compat2 compatibility layer. This requires prefixing any incompatible .await call with .compat()

async fn index() -> impl Responder {
    let client = DynamoDbClient::new("[region]");
    let tables = client.list_tables(list_tables_input).compat().await;
    // ...
}

Or you could downgrade rusoto to an older version that uses tokio v0.2:

rusoto_core = "0.43"
Ibraheem Ahmed
  • 11,652
  • 2
  • 48
  • 54
  • 1
    Thank you very much for the fast and detailed reply. I hoped tokio-compat2 might be the answer. Unfortunately, after [adding tokio-compat2](https://github.com/mattroberts297/hello_actix_rusoto/compare/master...compat-attempt) I still get the same run time error. [Upgrading actix](https://github.com/mattroberts297/hello_actix_rusoto/compare/master...try-and-upgrade-actix) results in multiple compile time errors (related to dependencies). I appreciate your help and patience! – Matt Roberts Feb 09 '21 at 19:52
  • 1
    @MattRoberts The latest `actix-rt` release broke 4.0.0-beta.1, and there are workarounds [here](https://github.com/actix/actix-web/issues/1944). I am not sure why `tokio-compat2` wouldn't be working.... your best bet is probably to downgrade rusoto until actix v4.0 is released. – Ibraheem Ahmed Feb 09 '21 at 20:19
  • 2
    Thank you @ibraheem-ahmed. Downgrading `rusoto_core` and `rusoto_dynamo` to 0.43 worked. I have made it work with sync() and tokio Core. I just need to refactor the Core into the actix app state and then will edit your answer to include solution (provided you're happy with that). Appreciate the workaround for the upgrade path also. Thank you again. – Matt Roberts Feb 09 '21 at 21:02
  • 1
    Just looping back round to this. In the end I went the upgrade path. Downgrading to rusoto did work, but I could only get sync() working at runtime. I think that would mean blocking current thread (which seems like it wouldn't scale). [Link to branch](https://github.com/mattroberts297/hello_actix_rusoto/tree/try-and-upgrade-actix) that works at compile-time and runtime. Thanks again. – Matt Roberts Feb 12 '21 at 16:53