Rust Axum 接口中断的研究
在使用axum写接口handle的时候,有时候会遇到接口处理资源消耗多、时间长的情况,由于时间比较长,客户端有可能会断开连接,同时axum后端也会在适合的时候中断handle的执行,本文研究了中断的时机。
如下代码写了一个示例,其中sleep是使用的同步的,为了展示其无法中断的特性。
async fn handle() -> (StatusCode, String) {
println!("start request");
for i in 0..5 {
println!("rank {}", i);
std::thread::sleep(std::time::Duration::from_secs(1));
}
println!("end request");
(StatusCode::OK, "Hello, World!".into())
}这时候客户端请求并立马中断,服务端打印:
start request
rank 0
rank 1
rank 2
rank 3
rank 4
end request可以看到代码没有中断执行
修改代码如下,将同步sleep改为异步:
async fn handle() -> (StatusCode, String) {
println!("start request");
for i in 0..5 {
println!("rank {}", i);
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
}
println!("end request");
(StatusCode::OK, "Hello, World!".into())
}这时候再次请求客户端并立马中断,服务端打印:
start request
rank 0可以看到这次代码中断了,这个所谓的中断时机就是await ,axum会在每次控制权交回前,检查连接是否中断,如果中断,则不再执行后续代码
从上面的例子可得,如果handle中存在一些耗时耗资源的操作,想要手动控制客户端断开时的中断代码,可以通过交出异步控制权去实现中断代码,如下:
async fn handle() -> (StatusCode, String) {
func1(); // 耗时操作,客户端可能断开连接
tokio::task::yield_now().await; // 交出异步控制权,不再执行后面的代码
func2(); // 耗资源操作,当客户端断开连接时,不再执行这一端
(StatusCode::OK, "Hello, World!".into())
}
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Ryan的折腾日记
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果