Reputation: 1408
I'm using tokio
to create a new thread to execute a task on file paths found using walkdir. It basically looks like follows:
pub async fn hash_tree(start_path: &Path) -> std::io::Result<()> {
for entry in WalkDir::new(start_path) {
let file_path_entry = entry.unwrap();
let file_path = file_path_entry.path();
let handle = tokio::spawn(async move {
hashing::hash_file(file_path).await.unwrap();
});
}
The problem with this code is that the file path doesn't live long enough. Rust fails with:
error[E0597]: `file_path_entry` does not live long enough
--> src/main.rs:44:25
|
44 | let file_path = file_path_entry.path();
| ^^^^^^^^^^^^^^^^^^^^^^
| |
| borrowed value does not live long enough
| argument requires that `file_path_entry` is borrowed for `'static`
...
61 | }
| - `file_path_entry` dropped here while still borrowed
I understand the issue but I'm not sure how to tackle it. Would it be better to first gather all the file_path
s in a vector and then push them into co-routines? I would rather prefer to kick the spawned task off as soon as it is found. Can I alternatively push copies of the file_path
s to a vector that is owned by the outer scope so that I can make sure that they live long enough (EDIT: tried push
ing the paths onto a vector with greater scope but that didn't work either)?
What would be alternative/better ways to handle that?
Upvotes: 0
Views: 831
Reputation: 1408
Thanks Netwave and Masklinn! What finally worked was moving a clone of file_path_entry.clone()
. As Masklinn pointed out, path
is also borrowed. So, this works:
for entry in WalkDir::new(start_path).follow_links(false) {
let file_path_entry = entry.unwrap();
let handle = tokio::spawn(async move {
hashing::hash_file(file_path_entry.clone()).await.unwrap();
});
Upvotes: 1