clippy:无法在线程之间安全地发送将来

问题描述

我想同时上传文件,但有一个上限,例如最多4个任务,为此,我正在使用FuturesUnordered,就像下面的code片段一样:

    let mut tasks = FuturesUnordered::new();

    let bin_parts = db_parts.iter().values();
    for bin_part in bin_parts {
        if let Ok(p) = bin_part {
            let part: Part = from_reader(&p[..])?;
            tasks.push(async { upload_part(s3,key,file,&upload_id,sdb,part).await });

            // limit to N threads (4 for example)
            if tasks.len() == threads {
                while let Some(r) = tasks.next().await {
                    if r.is_ok() {
                        pb.inc(1)
                    }
                }
            }
        }
    }

    // consume remaining tasks
    loop {
        if let Some(r) = tasks.next().await {
            if r.is_ok() {
                pb.inc(1)
            }
        } else {
            pb.finish();
            break;
        }
    }

    if !db_parts.is_empty() {
        return Err(anyhow!("could not upload all parts"));
    }

    // Complete Multipart Upload
    let uploaded = sdb.uploaded_parts()?;
    let action = actions::CompleteMultipartUpload::new(key,uploaded);
    let rs = action.request(s3).await?;

代码可以正常工作,但是我对clippy的输出不甚了解,我正在这样运行它:

cargo clippy --all-targets --all-features -- -D clippy::nursery -D warnings

这是错误:

error: future cannot be sent between threads safely
   --> src/s3m/multipart_upload.rs:36:6
    |
36  | ) -> Result<String> {
    |      ^^^^^^^^^^^^^^ future returned by `multipart_upload` is not `Send`
    |
    = note: `-D clippy::future-not-send` implied by `-D clippy::nursery`
note: future is not `Send` as this value is used across an await
   --> src/s3m/multipart_upload.rs:116:14
    |
80  |     let bin_parts = db_parts.iter().values();
    |         --------- has type `impl std::iter::DoubleEndedIterator` which is not `Send`
...
116 |     let rs = action.request(s3).await?;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here,with `bin_parts` maybe used later
...
125 | }
    | - `bin_parts` is later dropped here
    = note: `*const crossbeam_epoch::internal::Local` doesn't implement `std::marker::Send`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#future_not_send

搜索该主题似乎是因为没有删除bin_part变量,并且在某些情况下可以通过将内部作用域与{}一起使用来完成此操作,但我仍然找不到知道如何改善/解决这个问题。

我尝试使用范围:

{
let bin_parts = db_parts.iter().values();
    for bin_part in bin_parts {
        if let Ok(p) = bin_part {
            let part: Part = from_reader(&p[..])?;
            tasks.push(async { upload_part(s3,part).await });

            // limit to N threads (4 for example)
            if tasks.len() == threads {
                while let Some(r) = tasks.next().await {
                    if r.is_ok() {
                        pb.inc(1)
                    }
                }
            }
        }
    }
}

但是会出现相同的错误:

error: future cannot be sent between threads safely
  --> src/s3m/multipart_upload.rs:36:6
   |
36 | ) -> Result<String> {
   |      ^^^^^^^^^^^^^^ future returned by `multipart_upload` is not `Send`
   |
   = note: `-D clippy::future-not-send` implied by `-D clippy::nursery`
note: future is not `Send` as this value is used across an await
  --> src/s3m/multipart_upload.rs:89:41
   |
81 |         let bin_parts = db_parts.iter().values();
   |             --------- has type `impl std::iter::DoubleEndedIterator` which is not `Send`
...
89 |                     while let Some(r) = tasks.next().await {
   |                                         ^^^^^^^^^^^^^^^^^^ await occurs here,with `bin_parts` maybe used later
...
97 |     }
   |     - `bin_parts` is later dropped here

循环后,我尝试了drop

drop(bin_parts);

这是我得到的错误:

error[E0382]: use of moved value: `bin_parts`
  --> src/s3m/multipart_upload.rs:96:10
   |
80 |     let bin_parts = db_parts.iter().values();
   |         --------- move occurs because `bin_parts` has type `impl std::iter::DoubleEndedIterator`,which does not implement the `Copy` trait
81 |     for bin_part in bin_parts {
   |                     ---------
   |                     |
   |                     value moved here
   |                     help: consider borrowing to avoid moving into the for loop: `&bin_parts`
...
96 |     drop(bin_parts);
   |          ^^^^^^^^^ value used here after move

error[E0382]: use of moved value: `bin_parts`
  --> src/s3m/multipart_upload.rs:96:10
   |
80 |     let bin_parts = db_parts.iter().values();
   |         --------- move occurs because `bin_parts` has type `impl std::iter::DoubleEndedIterator`,which does not implement the `Copy` trait
81 |     for bin_part in bin_parts {
   |                     ---------
   |                     |
   |                     value moved here
   |                     help: consider borrowing to avoid moving into the for loop: `&bin_parts`
...
96 |     drop(bin_parts);
   |          ^^^^^^^^^ value used here after move

由于已移动,我无法删除该值。

有什么想法吗?

谢谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...