Rust Axum后端共享可变状态实现及编译错误求助
关于Axum共享状态与Handler编译错误的问题
背景
我正在基于Axum和HTMX开发类ChatGPT网站,在Axum后端实现共享可变状态时遇到困难。参考了Axum官方的键值存储示例,但克隆后无法编译,担心参考了过时资料。
当前main函数代码与疑惑
我的main()函数代码如下:
pub type SharedState = Arc<RwLock<AppState>>; #[derive(Clone, Debug, Deserialize, Serialize)] pub struct AppState { chats: Vec<Chat>, current_chat_idx: u8, } #[tokio::main] async fn main() { let state = SharedState::default(); let router: Router<()> = Router::new() .route("/", get(home)) .route("/chat/:current_agent", get(chat)) .route("/snippets/chat_list", get(chat_list)) .route("/snippets/chat_buttons", get(chat_buttons)) .route("/snippets/chat_history", get(chat_history)) .layer(Extension(state)) .with_state(AppState::default()); axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) .serve(router.into_make_service()) .await .unwrap(); }
这段代码能编译运行,但我有个疑问:既然通过.layer()已经能访问SharedState结构体,为什么还要用.with_state()传入另一个AppState实例?这是不是内存浪费且无意义的操作?
正常工作的端点代码
我编写的部分端点使用state: Extension<SharedState>作为参数,能正常编译且网页端工作正常:
pub async fn chat_history(state: Extension<SharedState>) -> Html<String> { let mut shared_state = state.write().unwrap(); let agent = shared_state.current_agent(); let messages: Vec<MessageRender> = agent .memory .cache() .as_ref() .into_iter() .map(|m| MessageRender::from(m)) .collect(); let template = fs::read_to_string("src/html/snippets/chat_history.html").unwrap(); let r = render!(&template, messages => messages); Html(r) } pub async fn chat_list(state: Extension<SharedState>) -> Html<String> { let shared_state = state.read().unwrap(); let current_chat_name = &shared_state.current_chat().name; println!( "Chat list current name, idx: {}, {}", current_chat_name, state.read().unwrap().current_chat_idx ); let template = fs::read_to_string("src/html/snippets/chat_list.html").unwrap(); let r = render!(&template,chats => shared_state.chats, current_chat_name => current_chat_name ); Html(r) }
编译错误的端点与问题
但当我尝试编译如下端点时:
pub async fn post_prompt( state: Extension<super::SharedState>, Form(prompt): Form<PromptForm>, ) -> Html<String> { let mut shared_state = state.write().unwrap(); let agent = shared_state.current_agent(); let res = agent.prompt(prompt.user_input).await; if let Ok(response) = res { println!("{}", response); } Html(String::new()) }
出现以下错误:
error[E0277]: the trait bound `fn(axum::Extension<Arc<std::sync::RwLock<AppState>>>, Form<PromptForm>) -> impl Future<Output = axum::response::Html<std::string::String>> {api::post_prompt}: Handler<_, _, _>` is not satisfied --> src/main.rs:83:58 | 83 | .route("/chat/:current_agent/prompt_agent", post(post_prompt)) | ---- ^^^^^^^^^^^ the trait `Handler<_, _, _>` is not implemented for fn item `fn(axum::Extension<Arc<std::sync::RwLock<AppState>>>, Form<PromptForm>) -> impl Future<Output = axum::response::Html<std::string::String>> {api::post_prompt}` | | | required by a bound introduced by this call | = help: the following other types implement trait `Handler<T, S, B>`: <Layered<L, H, T, S, B, B2> as Handler<T, S, B2>> <MethodRouter<S, B> as Handler<(), S, B>>
我尝试移除Form参数,仅保留Extension参数,但仍遇到相同错误,恳请帮助。
内容的提问来源于stack exchange,提问作者voidkandy
相关产品推荐
相关产品推荐

