You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 11:05:47