Rust异步Trait实现报错:Future无法安全跨线程发送
解决
future cannot be sent between threads safely错误 问题原因
这个错误的核心是:async_trait为insert_one方法生成的异步Future未实现Send trait,但Warp的多线程运行时要求Future必须具备Send特性。直接诱因是insert_one方法的new_document参数使用了impl Borrow<T>,却未明确标注Send约束,导致async_trait无法自动推导出生成的Future满足Send要求。
解决方案
给insert_one方法的new_document参数添加Send约束,同步修改Trait定义与实现代码:
修改后的Trait定义
use std::borrow::Borrow; use async_trait::async_trait; use mongodb::{ bson::Document, error::Error, options::FindOneOptions, results::InsertOneResult, Client, }; use serde::{de::DeserializeOwned, Serialize}; #[async_trait] pub trait Repository<'a> { fn with_client(client: &'a Client) -> Self; async fn find_one<'b, T: DeserializeOwned + Sync + Send + Unpin>( &self, filter: Document, find_one_options: FindOneOptions, ) -> Result<Option<T>, Error>; async fn insert_one<'b, T: DeserializeOwned + Sync + Send + Unpin + Serialize>( &self, new_document: impl Borrow<T> + Send, // 添加+ Send约束 ) -> Result<String, String>; }
修改后的实现代码
use std::borrow::Borrow; use async_trait::async_trait; use mongodb::{ bson::{doc, oid::ObjectId, Document}, error::Error, options::FindOneOptions, results::InsertOneResult, Client, }; use serde::{de::DeserializeOwned, Serialize}; pub struct MessagesRepository<'a> { pub(crate) client: &'a Client, } #[async_trait] impl<'a> super::Repository<'a> for MessagesRepository<'a> { fn with_client(client: &'a Client) -> Self { MessagesRepository { client: client } } async fn find_one<'b, T: DeserializeOwned + Sync + Send + Unpin>( &self, filter: Document, find_one_options: FindOneOptions, ) -> Result<Option<T>, Error> { let collection = self .client .database("App") .collection::<T>("Messages"); collection.find_one(filter, find_one_options).await } async fn insert_one<'b, T: DeserializeOwned + Sync + Send + Unpin + Serialize>( &self, new_document: impl Borrow<T> + Send, // 添加+ Send约束 ) -> Result<String, String> { let collection = self .client .database("App") .collection::<T>("Messages"); let result = collection.insert_one(new_document, None).await; match result { Ok(_) => Ok("Success".to_string()), Err(_) => Err("Error".to_string()), } } }
补充说明
MongoDB的Client本身实现了Send + Sync,因此MessagesRepository中的引用不会影响Send特性。添加Send约束后,async_trait能正确推导出生成的Future满足Send要求,适配Warp的多线程运行环境。
内容的提问来源于stack exchange,提问作者LukasDeco
相关产品推荐
相关产品推荐

