I am using the Warp crate for a web service, but I am having problems getting it running from my non-async main.
I have tried several ways and the closest I have gotten is this:
Cargo.toml
[dependencies]
warp = "0.3"
futures = "0.3"
Code:
use std::collections::HashMap;
use std::thread::{sleep, spawn};
use std::time;
use warp::{Filter};
use futures::executor::block_on;
async fn get_ap_list() -> Result<impl warp::Reply, warp::Rejection> {
let mut result = HashMap::new();
// TODO: Get a full list
result.insert("SSID", "rossless_24");
Ok(warp::reply::json(&result))
}
async fn start_ap_server() {
println!("AP server");
let get_ap = warp::get()
.and(warp::path("ap"))
.and(warp::path("list"))
.and(warp::path::end())
.and_then(get_ap_list);
warp::serve(get_ap)
.run(([0, 0, 0, 0], 3030))
.await;
}
// This intermediate function seem a bit redundant but I can't seem to spawn the async server directly
fn init_ap_server() {
println!("Init AP server");
let future = start_ap_server();
block_on(future);
}
fn main() {
let _t1 = spawn(move || {
init_ap_server()
});
// Make sure main is still running
loop {
println!("Alive for test.");
sleep(time::Duration::from_millis(5000));
}
}
That seems to work but I get:
thread '<unnamed>' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime', /home/tross/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.5.0/src/runtime/context.rs:18:26
Googling around I see that it is probably a Tokio version mismatch, but I don't even have Tokio in my dependencies, I am getting it from Warp.
Taking a step back, is there a simpler way to get what I want? I just want to launch some async code running (probably on its own thread) while leaving main alive and happy.
warp
itself does pull in thetokio
dependency but it does not come with thert
feature:So there is no runtime to execute the futures on. In order to get a
tokio::Runtime
you can explicitly spawn aRuntime
and callblock_on
on that runtime:with: