use crate::{
config::ForgeConfig,
debug::debug,
error::{error_utils, ForgeResult},
metrics,
middleware::MiddlewareStack,
};
use mf_state::{state::State, transaction::Transaction};
use std::sync::Arc;
use std::time::Instant;
pub struct MiddlewareHelper;
impl MiddlewareHelper {
pub async fn run_before_middleware(
transaction: &mut Transaction,
middleware_stack: &MiddlewareStack,
config: &ForgeConfig,
) -> ForgeResult<()> {
debug!("执行前置中间件链");
let timeout = std::time::Duration::from_millis(
config.performance.middleware_timeout_ms,
);
for middleware in &middleware_stack.middlewares {
let start_time = Instant::now();
match tokio::time::timeout(
timeout,
middleware.before_dispatch(transaction),
)
.await
{
Ok(Ok(())) => {
metrics::middleware_execution_duration(
start_time.elapsed(),
"before",
middleware.name().as_str(),
);
continue;
},
Ok(Err(e)) => {
return Err(error_utils::middleware_error(format!(
"前置中间件执行失败: {e}"
)));
},
Err(_) => {
return Err(error_utils::middleware_error(format!(
"前置中间件执行超时({}ms)",
config.performance.middleware_timeout_ms
)));
},
}
}
Ok(())
}
pub async fn run_after_middleware(
state: &mut Option<Arc<State>>,
transactions: &mut [Arc<Transaction>],
middleware_stack: &MiddlewareStack,
config: &ForgeConfig,
) -> ForgeResult<()> {
debug!("执行后置中间件链");
let timeout = std::time::Duration::from_millis(
config.performance.middleware_timeout_ms,
);
for middleware in &middleware_stack.middlewares {
let start_time = Instant::now();
let middleware_result = match tokio::time::timeout(
timeout,
middleware.after_dispatch(state.clone(), transactions),
)
.await
{
Ok(Ok(result)) => {
metrics::middleware_execution_duration(
start_time.elapsed(),
"after",
middleware.name().as_str(),
);
result
},
Ok(Err(e)) => {
return Err(error_utils::middleware_error(format!(
"后置中间件执行失败: {e}"
)));
},
Err(_) => {
return Err(error_utils::middleware_error(format!(
"后置中间件执行超时({}ms)",
config.performance.middleware_timeout_ms
)));
},
};
if middleware_result.is_some() {
}
}
Ok(())
}
}