I'm new to actix, and I'm trying to understand how I can run a server on one thread and send requests from another.
This is the code I have so far
use actix_web::{web, App, HttpResponse, HttpServer};
use std::{sync::mpsc::channel, thread};
#[actix_web::main]
async fn main() {
let (tx, rx) = channel();
thread::spawn(move || {
let srv =
HttpServer::new(|| App::new().default_service(web::to(|| HttpResponse::NotFound())))
.bind("localhost:12347")
.unwrap()
.run();
let _ = tx.send(srv);
});
reqwest::get("http://localhost:12347").await.unwrap();
let srv = rx.recv().unwrap();
srv.handle().stop(false).await;
}
It compiles just fine, but it gets stuck on on sending the request. It seems like the server is running, soI can't figure out why I am not getting a response.
EDIT: As suggested by @Finomnis and @cafce25,I changed the code to use tasks instead of threads, and await
ed te result of .run()
use actix_web::{web, App, HttpResponse, HttpServer};
use std::{sync::mpsc::channel, thread};
#[actix_web::main]
async fn main() {
let (tx, rx) = channel();
tokio::spawn(async move {
let srv =
HttpServer::new(|| App::new().default_service(web::to(|| HttpResponse::NotFound())))
.bind("localhost:12347")
.unwrap()
.run();
let _ = tx.send(srv.handle());
srv.await.unwrap();
});
reqwest::get("http://localhost:12347").await.unwrap();
let handle = rx.recv().unwrap();
handle.stop(false).await;
}
which solves the problem. I'm still curious if it is possible to do it on different threads since I can't use await
inside a synchronous function.
async
programming usually shouldn't be mixed (until a deep understanding of howasync
works is reached), instead spawn a new task. – Bitchrequwest::get(...)
deadlocks cause the server doesn't handle requests yet. Or in other words they should follow your first suggestion @Finomnis. – Hydrodynamicthread
totokio
(and slightly modifying the closure) still gives the same behaviour. So I don't think this is the source of the problem – Torres.await
the results of.run()
for any listening to happen. – HydrodynamicHttpServer
itself already does multithreading internally. Moving it onto a different thread will give you no performance benefit. As mentioned earlier, move it to a task instead. Not on a tokio task, though -#[actix_web::main]
has its own runtime. You need to spawn an actix-web task instead. Of course you can use the#[tokio::main]
runtime instead if you want to spawn tokio tasks.actix-web
is compatible with that. – Bitchrun()
:This method starts a number of HTTP workers in separate threads.
. You don't need to put it on a thread yourself, justspawn
the result ofrun()
. And no, you cannot go from asynchronous to synchronous and back to asynchronous. Once you are in synchronous land, you have no good way of returning back to async. – Bitch