How to run a server in a thread? #2501
-
SummaryI saw an example of this from actix-web: run-in-thread How to do it use axum? axum version0.7.3 |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
The easiest way is just to spawn a new async task with use std::time::Duration;
use axum::{routing::get, Router};
use tower_http::timeout::TimeoutLayer;
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(|| async { "Hello, World!" }))
.layer(TimeoutLayer::new(Duration::from_secs(10)));
let (close_tx, close_rx) = tokio::sync::oneshot::channel();
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await
.unwrap();
let server_handle = tokio::spawn(async {
axum::serve(listener, app)
.with_graceful_shutdown(async move {
_ = close_rx.await;
})
.await
.unwrap();
});
println!("waiting 5 seconds");
tokio::time::sleep(Duration::from_secs(5)).await;
println!("telling server to shutdown");
_ = close_tx.send(());
println!("waiting for server to gracefully shutdown");
_ = server_handle.await;
} Assuming you're using tokio's multi-threaded scheduler, which is the default, then tokio will schedule things across threads. This is what I'd recommend. You can also run axum on a dedicated thread using a single threaded tokio runtime: use std::time::Duration;
use axum::{routing::get, Router};
use tower_http::timeout::TimeoutLayer;
fn main() {
let (close_tx, close_rx) = tokio::sync::oneshot::channel();
let server_handle = std::thread::spawn(|| run_server(close_rx));
println!("waiting 5 seconds");
std::thread::sleep(Duration::from_secs(5));
println!("telling server to shutdown");
_ = close_tx.send(());
println!("waiting for server to gracefully shutdown");
_ = server_handle.join();
}
fn run_server(close_rx: tokio::sync::oneshot::Receiver<()>) {
let app = Router::new()
.route("/", get(|| async { "Hello, World!" }))
.layer(TimeoutLayer::new(Duration::from_secs(10)));
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
rt.block_on(async move {
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await
.unwrap();
axum::serve(listener, app)
.with_graceful_shutdown(async move {
_ = close_rx.await;
})
.await
.unwrap();
});
} |
Beta Was this translation helpful? Give feedback.
-
I'm having a similar problem, but I have a hybrid situation: I want to run axum on a blocking dedicated thread using tokio's My problem is that currently the HTTP task does not respond to HTTP requests (http requests hang).
|
Beta Was this translation helpful? Give feedback.
The easiest way is just to spawn a new async task with
tokio::spawn
: