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

为何Axum v0.7中的Stream不再实现Sync trait?

Axum v0.7升级后文件上传编译错误原因分析

问题背景

在使用Axum v0.6时,可通过以下代码调用要求Pin<Box<(dyn AsyncRead + Send + Sync)>>参数的create_file函数实现文件上传:

pub async fn create_file(
    &self,
    name: &str,
    reader: Pin<Box<(dyn AsyncRead + Send + Sync)>>,
) -> Result<CreatedFile>

Axum v0.6处理器代码:

// axum's handler
pub async fn upload(stream: BodyStream) -> Result<Response, StatusCode> {
    let stream = stream.map_err(|err| io::Error::new(io::ErrorKind::Other, err));

    let res = file_create("filename", Box::pin(StreamReader::new(stream))).await?;

    Ok((StatusCode::CREATED, "Ok").into_response())
}

升级到Axum v0.7后,修改处理器代码为:

// axum's handler
pub async fn upload(request: Request) -> Result<Response, StatusCode> {
    let stream = request
        .into_body()
        .into_data_stream()
        .map_err(|err| io::Error::new(io::ErrorKind::Other, err));

    let res = file_create("filename", Box::pin(StreamReader::new(stream))).await?;

    Ok((StatusCode::CREATED, "Ok").into_response())
}

此时出现编译错误:

error[E0277]: `(dyn axum::body::HttpBody<Data = tokio_util::bytes::Bytes, Error = axum::Error> + std::marker::Send + 'static)` cannot be shared between threads safely
    |
59  |             Box::pin(StreamReader::new(stream)),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn axum::body::HttpBody<Data = tokio_util::bytes::Bytes, Error = axum::Error> + std::marker::Send + 'static)` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `(dyn axum::body::HttpBody<Data = tokio_util::bytes::Bytes, Error = axum::Error> + std::marker::Send + 'static)`
    = note: required for `std::ptr::Unique<(dyn axum::body::HttpBody<Data = tokio_util::bytes::Bytes, Error = axum::Error> + std::marker::Send + 'static)>` to implement `std::marker::Sync`
note: required because it appears within the type `Box<dyn HttpBody<Data = Bytes, Error = Error> + Send>`
    |
195 | pub struct Box<
    |            ^^^
note: required because it appears within the type `Pin<Box<dyn HttpBody<Data = Bytes, Error = Error> + Send>>`
    |
410 | pub struct Pin<P> {
    |            ^^^
note: required because it appears within the type `UnsyncBoxBody<Bytes, Error>`
    |
17  | pub struct UnsyncBoxBody<D, E> {
    |            ^^^^^^^^^^^^^
note: required because it appears within the type `Body`
    |
39  | pub struct Body(BoxBody);
    |            ^^^^
note: required because it appears within the type `BodyDataStream`
    |
140 | pub struct BodyDataStream {
    |            ^^^^^^^^^^^^^^
note: required because it appears within the type `IntoStream<BodyDataStream>`
    |
12  |     pub struct IntoStream<St> {
    |                ^^^^^^^^^^
note: required because it appears within the type `Map<IntoStream<BodyDataStream>, MapErrFn<{closure@file.rs:48:18}>>`
    |
15  |     pub struct Map<St, F> {
    |                ^^^
note: required because it appears within the type `MapErr<BodyDataStream, {closure@file.rs:48:18}>`
    |
63  |     MapErr<St, F>(
    |     ^^^^^^
note: required because it appears within the type `StreamReader<MapErr<BodyDataStream, {closure@file.rs:48:18}>, Bytes>`
    |
156 | pub struct StreamReader<S, B> {
    |            ^^^^^^^^^^^^
    = note: required for the cast from `Pin<Box<StreamReader<MapErr<BodyDataStream, {closure@file.rs:48:18}>, Bytes>>>` to `std::pin::Pin<std::boxed::Box<(dyn tokio::io::AsyncRead + std::marker::Send + std::marker::Sync + 'static)>>`

错误原因

  • Axum v0.7的Body类型变更:Axum v0.7默认使用UnsyncBoxBody作为Body的底层实现,该类型仅实现了Send trait,未实现Sync trait,意味着它无法安全地在线程间共享。
  • 数据流的Sync特性缺失:调用request.into_body().into_data_stream()得到的BodyDataStream,内部依赖未实现Sync的Body类型,导致整个数据流不满足Sync要求。
  • 类型匹配失败:create_file函数要求参数必须同时满足AsyncRead + Send + Sync,但通过StreamReader包装后的数据流仅具备AsyncRead + Send特性,缺少Sync,因此无法完成类型转换,触发编译错误。
  • v0.6与v0.7的差异:Axum v0.6中的BodyStream内部实现满足Send + Sync,因此当时的代码可以正常编译;v0.7改用非线程安全的UnsyncBoxBody作为默认Body,直接导致了该兼容性问题。

内容的提问来源于stack exchange,提问作者Fred Hors

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 17:22:49