超时中间件
2026/3/11大约 1 分钟hyperlanewebrustmiddlewaretimeout
超时中间件
原生写法
use hyperlane::{
tokio::{
spawn,
time::{sleep, timeout},
},
*,
};
use std::time::Duration;
struct HttpVersionMiddleware;
struct TimeoutMiddleware;
struct IndexRoute;
struct ResponseMiddleware;
impl ServerHook for HttpVersionMiddleware {
async fn new(_ctx: &mut Context) -> Self {
Self
}
async fn handle(self, ctx: &mut Context) {
ctx.get_mut_response().set_version(HttpVersion::Http1_1);
}
}
impl ServerHook for TimeoutMiddleware {
async fn new(_ctx: &mut Context) -> Self {
Self
}
async fn handle(self, ctx: &mut Context) {
let ctx_addr: usize = ctx.into();
let new_ctx: &mut Context = ctx_addr.into();
spawn(async move {
timeout(Duration::from_millis(100), async move {
new_ctx
.get_mut_response()
.set_status_code(504)
.set_body("timeout");
new_ctx.set_aborted(true);
if new_ctx.try_send().await.is_err() {
new_ctx.set_closed(true);
}
})
.await
.unwrap();
});
}
}
impl ServerHook for IndexRoute {
async fn new(_ctx: &mut Context) -> Self {
Self
}
async fn handle(self, ctx: &mut Context) {
sleep(Duration::from_secs(1)).await;
ctx.get_mut_response()
.set_status_code(200)
.set_body("Hello, world!");
}
}
impl ServerHook for ResponseMiddleware {
async fn new(_ctx: &mut Context) -> Self {
Self
}
async fn handle(self, ctx: &mut Context) {
if ctx.try_send().await.is_err() {
ctx.set_aborted(true).set_closed(true);
}
}
}
#[tokio::main]
async fn main() {
Server::default()
.request_middleware::<HttpVersionMiddleware>()
.request_middleware::<TimeoutMiddleware>()
.response_middleware::<ResponseMiddleware>()
.route::<IndexRoute>("/")
.run()
.await
.unwrap()
.wait()
.await
}宏写法
use hyperlane::{
tokio::{
spawn,
time::{sleep, timeout},
},
*,
};
use hyperlane_utils::*;
use std::time::Duration;
#[request_middleware(1)]
struct HttpVersionMiddleware;
#[request_middleware(2)]
struct TimeoutMiddleware;
#[route("/")]
struct IndexRoute;
#[response_middleware(1)]
struct ResponseMiddleware;
impl ServerHook for HttpVersionMiddleware {
async fn new(_ctx: &mut Context) -> Self {
Self
}
#[response_version(HttpVersion::Http1_1)]
async fn handle(self, ctx: &mut Context) {}
}
impl ServerHook for TimeoutMiddleware {
async fn new(_ctx: &mut Context) -> Self {
Self
}
async fn handle(self, ctx: &mut Context) {
let ctx_addr: usize = ctx.into();
let new_ctx: &mut Context = ctx_addr.into();
spawn(async move {
timeout(Duration::from_millis(100), async move {
new_ctx
.get_mut_response()
.set_status_code(504)
.set_body("timeout");
new_ctx.set_aborted(true);
if new_ctx.try_send().await.is_err() {
new_ctx.set_closed(true);
}
})
.await
.unwrap();
});
}
}
impl ServerHook for IndexRoute {
async fn new(_ctx: &mut Context) -> Self {
Self
}
#[response_status_code(200)]
#[response_body("Hello, world!")]
async fn handle(self, ctx: &mut Context) {
sleep(Duration::from_secs(1)).await;
}
}
impl ServerHook for ResponseMiddleware {
async fn new(_ctx: &mut Context) -> Self {
Self
}
#[send]
async fn handle(self, ctx: &mut Context) {}
}
#[tokio::main]
async fn main() {
Server::default().run().await.unwrap().wait().await
}