|
| 1 | +use axum::{routing::get, Router, serve}; |
| 2 | +use std::net::SocketAddr; |
| 3 | +use tokio::{net::TcpListener, sync::mpsc}; |
| 4 | +use tokio::signal::unix::{signal, SignalKind}; |
| 5 | + |
| 6 | +#[tokio::main] |
| 7 | +async fn main() { |
| 8 | + let (shutdown_tx, mut shutdown_rx) = mpsc::channel::<()>(1); |
| 9 | + |
| 10 | + let app = Router::new() |
| 11 | + .route("/healthz", get(|| async { "OK\n" })) |
| 12 | + .route("/", get(|| async { "hello this is a rust http server\n" })) |
| 13 | + .route( |
| 14 | + "/quit", |
| 15 | + get({ |
| 16 | + let shutdown_tx = shutdown_tx.clone(); |
| 17 | + move || { |
| 18 | + let shutdown_tx = shutdown_tx.clone(); |
| 19 | + async move { |
| 20 | + let _ = shutdown_tx.send(()).await; |
| 21 | + "yes i am shutting down\n" |
| 22 | + } |
| 23 | + } |
| 24 | + })); |
| 25 | + |
| 26 | + let addr = SocketAddr::from(([0, 0, 0, 0], 3000)); |
| 27 | + let listener = TcpListener::bind(addr).await.unwrap(); |
| 28 | + |
| 29 | + println!("rust http server ready on {}", addr); |
| 30 | + |
| 31 | + let server = serve(listener, app); |
| 32 | + |
| 33 | + let mut term_signal = signal(SignalKind::terminate()).expect("failed to register SIGTERM handler"); |
| 34 | + let mut int_signal = signal(SignalKind::interrupt()).expect("failed to register SIGINT handler"); |
| 35 | + |
| 36 | + tokio::select! { |
| 37 | + _ = server.with_graceful_shutdown(async move { shutdown_rx.recv().await; }) => { println! ("done"); } |
| 38 | + _ = tokio::signal::ctrl_c() => { println!("terminating due to Ctrl+C"); } |
| 39 | + _ = term_signal.recv() => { println!("terminating due to SIGTERM"); } |
| 40 | + _ = int_signal.recv() => { println!("terminating due to SIGINT"); } |
| 41 | + } |
| 42 | + |
| 43 | + println!("rust http server down"); |
| 44 | +} |
0 commit comments