// src/server.rs
use axum::{
extract::Path,
response::{IntoResponse, Response},
routing::get,
};
pub struct Server {}
impl Server {
pub async fn run() -> Result<(), Box<dyn std::error::Error>> {
let axum_http_make_service = axum::Router::new()
.route("/:sec", get(wait_sec_event))
.into_make_service();
let http_server =
axum::Server::bind(&"0.0.0.0:4000".parse().unwrap()).serve(axum_http_make_service);
let http_handle = tokio::spawn(http_server);
let _ = tokio::try_join!(http_handle)?;
Ok(())
}
}
async fn wait_sec_event(Path(sec): Path<String>) -> Response {
let a = std::time::Duration::from_secs(sec.parse::<u64>().unwrap());
std::thread::sleep(a);
"yo".into_response()
}
// src/app.rs
use std::net::SocketAddr;
use crate::server;
pub struct App {
port: SocketAddr,
}
impl App {
pub fn new(p: SocketAddr) -> Self {
Self { port: p }
}
pub async fn run(self) -> Result<(), Box<dyn std::error::Error>> {
server::Server::run().await
}
}
// src/main.rs
use std::net::SocketAddr;
use app::App;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// build our application with a single route
let app = App::new(SocketAddr::from(([0, 0, 0, 0], 4000)));
app.run().await
}
pub mod app;
pub mod server;
当我试图实现一个axum服务器,我发现,如果我把axum::Server::bind(&"0.0.0.0:4000".parse().unwrap()).serve(axum_http_make_service);
到tokio::spawn
而不是仅仅await.unwrap()
它
服务器无法接受并行请求。
表示如果我执行curl 127.0.0.1:4000/10
则执行curl 127.0.0.1:4000/3
,
后一个请求将不会执行,直到第一个请求完成,如果我只是await.unwrap()
它不会发生。
你知道我可能在哪里出错吗?
您使用std::thread::sleep
阻塞线程,在异步环境中不应该这样做,因为它会阻止同一线程上的其他任务像您所经历的那样运行。使用tokio::time::sleep
代替:
async fn wait_sec_event(Path(sec): Path<String>) -> Response {
let a = std::time::Duration::from_secs(sec.parse::<u64>().unwrap());
tokio::time::sleep(a).await;
"yo".into_response()
}
我相信在行为上的差异是因为或多或少偶然的任务得到衍生在不同的线程在你的直接等待场景,而他们得到衍生在同一线程当使用tokio::spawn
。