问题描述
我想同时上传文件,但有一个上限,例如最多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 (将#修改为@)