Tide: Using Reqwest combined with Tide

Created on 13 Nov 2019  路  6Comments  路  Source: http-rs/tide

I'm trying to combine Tide with a current implementation we have that uses the Reqwest HTTP client. The problem comes when using a reqwest client inside a tide endpoint, as in that moment the reqwest client panics with the error no current reactor. As far as I know, reqwest uses the Tokio reactor, and Tide uses Hyper, which also uses the Tokio reactor.

I've set up a minimal example of what I want to achieve

// main.rs

async fn make_request(cx: tide::Context<()>) -> String {
    let resp: std::collections::HashMap<String, String> = reqwest::get("https://httpbin.org/ip")
        .await.expect("Error in reqwest")
        .json()
        .await.expect("Error parsing JSON");

    resp.get("origin").expect("Origin Key not present in response").to_string()
}

fn main() -> Result<(), std::io::Error> {
    let mut app = tide::App::new();
    app.at("/").get(make_request);
    Ok(app.serve("127.0.0.1:8000")?)
}
# Cargo.toml

[package]
name = "tide-reqwest-example"
version = "0.1.0"
authors = ["Whatever <[email protected]>"]
edition = "2018"

[dependencies]
tide = "0.3.0"
reqwest = { version = "0.10.0-alpha.2", features = ["default-tls", "json"] }

I've even tried adding #[tokio::main] in the main function (and making it async), but the result is the same.

Is there any way to solve this problem or making Tide use the Tokio reactor?

Most helpful comment

Hyper 0.13 is out! :) with tokio 0.2 and quite some performance improvements.

All 6 comments

@cquintana-verbio between differen tokio versions, reqwest and the alphas, I'm unsure where the error is exactly originating. I think asking the authors of those libraries might help pinpoint it faster.

However if you want to make HTTP requests within tide, consider using surf -- we'll be ensuring that both tide and surf work well together on top of the async-std runtime, so perhaps that might pose a suitable alternative:

use std::collections::HashMap;

async fn make_request(cx: tide::Context<()>) -> Result<String, Surf::Exception> {
    let resp: HashMap<String, String> = surf::get("https://httpbin.org/ip")
        .recv_json()
        .await?;

    resp.get("origin").expect("Origin Key not present in response").to_string()
}

fn main() -> Result<(), std::io::Error> {
    let mut app = tide::App::new();
    app.at("/").get(make_request);
    Ok(app.serve("127.0.0.1:8000")?)
}

It's probably because the underlying http-service is still using hyper 0.12 . Can http-service be updated to 0.13?

@acasajus hyper 0.13 is currently experimental (alpha 4, with impactful breaking changes planned), which doesn't match the stability guarantees we require for a library that underpins Tide.

Hyper 0.13 is out! :) with tokio 0.2 and quite some performance improvements.

thread 'async-std/executor' panicked at 'not currently running on the Tokio runtime.', /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/handle.rs:63:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1069
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1427
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:218
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:511
  11: rust_begin_unwind
             at src/libstd/panicking.rs:419
  12: core::panicking::panic_fmt
             at src/libcore/panicking.rs:111
  13: core::option::expect_failed
             at src/libcore/option.rs:1203
  14: core::option::Option<T>::expect
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/option.rs:347
  15: tokio::runtime::handle::Handle::current
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/handle.rs:63
  16: tokio::runtime::blocking::pool::spawn_blocking
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/blocking/pool.rs:65
  17: tokio::task::blocking::spawn_blocking
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/task/blocking.rs:69
  18: <hyper::client::connect::dns::GaiResolver as tower_service::Service<hyper::client::connect::dns::Name>>::call
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/client/connect/dns.rs:120
  19: <S as hyper::client::connect::dns::sealed::Resolve>::resolve
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/client/connect/dns.rs:332
  20: hyper::client::connect::dns::resolve::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/client/connect/dns.rs:342
  21: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  22: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  23: hyper::client::connect::http::HttpConnector<R>::call_async::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/client/connect/http.rs:307
  24: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  25: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  26: <hyper::client::connect::http::HttpConnector<R> as tower_service::Service<http::uri::Uri>>::call::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/client/connect/http.rs:248
  27: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  28: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
  29: <hyper::client::connect::http::HttpConnecting<R> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/client/connect/http.rs:388
  30: <futures_util::future::either::Either<A,B> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/either.rs:62
  31: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  32: <hyper_rustls::connector::HttpsConnector<T> as tower_service::Service<http::uri::Uri>>::call::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-rustls-0.20.0/src/connector.rs:126
  33: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  34: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
  35: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  36: reqwest::connect::Connector::connect_with_maybe_proxy::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.10.4/src/connect.rs:371
  37: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  38: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  39: reqwest::connect::with_timeout::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.10.4/src/connect.rs:500
  40: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  41: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
  42: <hyper::service::oneshot::Oneshot<S,Req> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/service/oneshot.rs:58
  43: <F as futures_core::future::TryFuture>::try_poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-core-0.3.4/src/future.rs:83
  44: <futures_util::future::try_future::map_err::MapErr<Fut,F> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/try_future/map_err.rs:43
  45: <F as futures_core::future::TryFuture>::try_poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-core-0.3.4/src/future.rs:83
  46: futures_util::future::try_future::try_chain::TryChain<Fut1,Fut2,Data>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/try_future/try_chain.rs:53
  47: <futures_util::future::try_future::and_then::AndThen<Fut1,Fut2,F> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/try_future/and_then.rs:46
  48: <futures_util::future::either::Either<A,B> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/either.rs:62
  49: <hyper::common::lazy::Lazy<F,R> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/common/lazy.rs:59
  50: futures_util::future::future::FutureExt::poll_unpin
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/future/mod.rs:507
  51: <futures_util::future::select::Select<A,B> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/select.rs:64
  52: futures_util::future::future::chain::Chain<Fut1,Fut2,Data>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/future/chain.rs:44
  53: <futures_util::future::future::then::Then<Fut1,Fut2,F> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/future/then.rs:44
  54: <F as futures_core::future::TryFuture>::try_poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-core-0.3.4/src/future.rs:83
  55: futures_util::future::try_future::try_chain::TryChain<Fut1,Fut2,Data>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/try_future/try_chain.rs:53
  56: <futures_util::future::try_future::and_then::AndThen<Fut1,Fut2,F> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/try_future/and_then.rs:46
  57: hyper::client::Client<C,B>::retryably_send_request::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/client/mod.rs:253
  58: <futures_util::future::poll_fn::PollFn<F> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/poll_fn.rs:54
  59: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
  60: <hyper::client::ResponseFuture as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.13.4/src/client/mod.rs:604
  61: <reqwest::async_impl::client::PendingRequest as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.10.4/src/async_impl/client.rs:1276
  62: <reqwest::async_impl::client::Pending as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.10.4/src/async_impl/client.rs:1255
  63: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  64: tgbot::api::Api::execute::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/tgbot-0.7.1/src/api.rs:158
  65: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  66: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  67: admin::telegram::Telegram::publish::{{closure}}
             at src/telegram.rs:74
  68: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  69: <futures_util::future::maybe_done::MaybeDone<Fut> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/maybe_done.rs:96
  70: admin::Application::publish::{{closure}}::{{closure}}
             at src/main.rs:86
  71: <futures_util::future::poll_fn::PollFn<F> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/poll_fn.rs:54
  72: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  73: admin::Application::publish::{{closure}}
             at src/main.rs:86
  74: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  75: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  76: admin::Application::try_posts::{{closure}}
             at src/main.rs:79
  77: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  78: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  79: admin::main::{{closure}}::{{closure}}::{{closure}}
             at src/main.rs:34
  80: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  81: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  82: <F as tide::endpoint::Endpoint<State>>::call::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/tide-0.6.0/src/endpoint.rs:68
  83: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  84: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
  85: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
  86: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  87: <tide::middleware::cookies::CookiesMiddleware as tide::middleware::Middleware<State>>::handle::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/tide-0.6.0/src/middleware/cookies.rs:54
  88: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  89: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
  90: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  91: <tide::server::Service<InnerState> as tide::endpoint::Endpoint<State>>::call::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/tide-0.6.0/src/server/mod.rs:386
  92: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  93: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
  94: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
  95: <tide::server::Service<State> as http_service::HttpService>::respond::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/tide-0.6.0/src/server/mod.rs:355
  96: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
  97: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
  98: <F as futures_core::future::TryFuture>::try_poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-core-0.3.4/src/future.rs:83
  99: <futures_util::future::try_future::into_future::IntoFuture<Fut> as core::future::future::Future>::poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/try_future/into_future.rs:34
 100: std::future::poll_with_tls_context
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:99
 101: <http_service_hyper::WrapConnection<H> as hyper::service::service::Service>::call::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/http-service-hyper-0.4.1/src/lib.rs:87
 102: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libstd/future.rs:44
 103: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f509b26a7730d721ef87423a72b3fdf8724b4afa/src/libcore/future/future.rs:118
 104: <F as futures_core::future::TryFuture>::try_poll
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-core-0.3.4/src/future.rs:83
 105: <futures_util::compat::compat03as01::Compat<Fut> as futures::future::Future>::poll::{{closure}}
             at /home/humb1t/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/compat/compat03as01.rs:121

Looks like any Tokio based library may end up with this issue, even if main will be #[tokio:main].

async-std starting with v1.6.0 now ships with a tokio02 feature flag that initializes tokio's TLS context whenever it starts a thread. This should fix most of the Tokio compat errors. It can be enabled by configuring it Cargo.toml as follows:

[dependencies.async-std]
version = "1.6.2"
features = ["tokio02"]

From there reqwest should work as expected!

Was this page helpful?
0 / 5 - 0 ratings