Do a synchronous http client fetch within an actix thread
Asked Answered
F

3

5

I have an actix endpoint, and I need to do a synchronous http client fetch to get some results, and return some data. My endpoints cannot use async, so I can't use any .await methods.

I've tried using reqwests blocking client in my endpoint like so:

{ ...

  let res = reqwest::blocking::get(&fetch_url)?
    .json::<MyResp>()?;
  ...

But it gives me the error:

thread 'main' panicked at 'Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.', /.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.9/src/runtime/enter.rs:19:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
Filmer answered 7/3, 2020 at 18:14 Comment(2)
Why can't your endpoints use async?Idou
Long story but its an extremely complicated websocket server using traits, WSSessionHandlers, and Streamhandlers, with only async allowed at the top.Filmer
D
3

you should try creating a new thread for that:

std::thread::spawn(move || {

    reqwest::blocking::get(&url).unwrap().json().unwrap()

}).join().unwrap()
Degroot answered 26/11, 2020 at 5:46 Comment(0)
F
0

I couldn't figure out how to get it working with reqwest (it must have some weird conflicts with actix), but for some reason it worked fine with chttp.

chttp::get(&fetch_url)?.text()?;

Filmer answered 7/3, 2020 at 18:49 Comment(1)
It worked with an older version of Reqwest, but a more recent version made the blocking client the same as the non-blocking but wrapped with a tokio::block_on. Actix also uses tokio, which does not support nested runtimes.Boastful
D
-3

You cannot use blocking functions inside async functions.

Instead of reqwest::blocking::get() use reqwest::get().await.

Digitoxin answered 24/4, 2020 at 17:37 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.