UpdatePathOutcome includes a "Failed" variant with path and error

This commit is contained in:
Tomáš Mládek 2021-12-05 13:22:13 +01:00
parent b5a013e973
commit 365987f261

View file

@ -80,11 +80,12 @@ pub async fn rescan_vault(
type UpdatePathResult = Result<UpdatePathOutcome>; type UpdatePathResult = Result<UpdatePathOutcome>;
#[derive(Debug, Clone)] #[derive(Debug)]
enum UpdatePathOutcome { enum UpdatePathOutcome {
Added(PathBuf), Added(PathBuf),
Unchanged(PathBuf), Unchanged(PathBuf),
Removed(PathBuf), Removed(PathBuf),
Failed(PathBuf, Error),
} }
fn _rescan_vault<T: AsRef<Path>>( fn _rescan_vault<T: AsRef<Path>>(
@ -92,7 +93,7 @@ fn _rescan_vault<T: AsRef<Path>>(
directory: T, directory: T,
job_container: Arc<RwLock<JobContainer>>, job_container: Arc<RwLock<JobContainer>>,
job_id: JobId, job_id: JobId,
) -> Result<Vec<UpdatePathResult>> { ) -> Result<Vec<UpdatePathOutcome>> {
let start = Instant::now(); let start = Instant::now();
info!("Vault rescan started."); info!("Vault rescan started.");
@ -123,16 +124,16 @@ fn _rescan_vault<T: AsRef<Path>>(
let count = RwLock::new(0_usize); let count = RwLock::new(0_usize);
let resolve_cache = Arc::new(Mutex::new(LruCache::new(256))); let resolve_cache = Arc::new(Mutex::new(LruCache::new(256)));
let total = path_entries.len() as f32; let total = path_entries.len() as f32;
let path_results: Vec<UpdatePathResult> = path_entries let path_outcomes: Vec<UpdatePathOutcome> = path_entries
.into_par_iter() .into_par_iter()
.map(|path| { .map(|path| {
let result = _process_directory_entry( let result = _process_directory_entry(
&rw_pool, &rw_pool,
&resolve_cache, &resolve_cache,
path, path.clone(),
&absolute_dir_path, &absolute_dir_path,
&existing_files, &existing_files,
)?; );
let mut cnt = count.write().unwrap(); let mut cnt = count.write().unwrap();
*cnt += 1; *cnt += 1;
@ -143,35 +144,43 @@ fn _rescan_vault<T: AsRef<Path>>(
.update_progress(&job_id, *cnt as f32 / total * 100.0) .update_progress(&job_id, *cnt as f32 / total * 100.0)
.unwrap(); .unwrap();
Ok(result) match result {
Ok(result) => result,
Err(error) => UpdatePathOutcome::Failed(path, error),
}
}) })
.collect(); .collect();
let existing_files = existing_files.read().unwrap(); let existing_files = existing_files.read().unwrap();
let cleanup_results = existing_files.iter().filter(|f| f.valid).map(|file| {
let connection = pool.get()?; let connection = pool.get()?;
connection.transaction::<_, Error, _>(|| { let cleanup_results = existing_files.iter().filter(|f| f.valid).map(|file| {
let trans_result = connection.transaction::<_, Error, _>(|| {
file_set_valid(&connection, file.id, false)?; file_set_valid(&connection, file.id, false)?;
// remove_object(&connection, )? // remove_object(&connection, )?
info!("Removed: {:?}", file.path); Ok(())
Ok(UpdatePathOutcome::Removed(PathBuf::from(file.path.clone())))
})
}); });
let mut failed: Vec<&Error> = vec![]; match trans_result {
Ok(_) => {
info!("Removed: {:?}", file.path);
UpdatePathOutcome::Removed(PathBuf::from(file.path.clone()))
}
Err(error) => UpdatePathOutcome::Failed(PathBuf::from(file.path.clone()), error),
}
});
let mut failed: Vec<(&PathBuf, &Error)> = vec![];
let mut created = 0; let mut created = 0;
let mut unchanged = 0; let mut unchanged = 0;
let mut deleted = 0; let mut deleted = 0;
for result in &path_results { for outcome in &path_outcomes {
match result { match outcome {
Ok(result) => match result {
UpdatePathOutcome::Added(_) => created += 1, UpdatePathOutcome::Added(_) => created += 1,
UpdatePathOutcome::Unchanged(_) => unchanged += 1, UpdatePathOutcome::Unchanged(_) => unchanged += 1,
UpdatePathOutcome::Removed(_) => deleted += 1, UpdatePathOutcome::Removed(_) => deleted += 1,
}, UpdatePathOutcome::Failed(path, err) => failed.push((path, err)),
Err(err) => failed.push(err),
} }
} }
@ -181,7 +190,7 @@ fn _rescan_vault<T: AsRef<Path>>(
failed.len(), failed.len(),
failed failed
.iter() .iter()
.map(|e| e.to_string()) .map(|(path, error)| format!("{:?}: {}", path, error))
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(", ") .join(", ")
) )
@ -200,7 +209,7 @@ fn _rescan_vault<T: AsRef<Path>>(
start.elapsed().as_secs() start.elapsed().as_secs()
); );
Ok(path_results.into_iter().chain(cleanup_results).collect()) Ok(path_outcomes.into_iter().chain(cleanup_results).collect())
} }
fn _process_directory_entry<P: AsRef<Path>>( fn _process_directory_entry<P: AsRef<Path>>(
@ -396,11 +405,9 @@ mod test {
assert!(rescan_result.is_ok()); assert!(rescan_result.is_ok());
let rescan_result = rescan_result.unwrap(); let rescan_result = rescan_result.unwrap();
assert_eq!(rescan_result.len(), 3); assert_eq!(rescan_result.len(), 3);
rescan_result.into_iter().for_each(|outcome| { rescan_result
assert!(outcome.is_ok()); .into_iter()
let outcome = outcome.unwrap(); .for_each(|outcome| assert!(matches!(outcome, UpdatePathOutcome::Added(_))));
assert!(matches!(outcome, UpdatePathOutcome::Added(_)))
});
// Modification-less rescan // Modification-less rescan
@ -414,11 +421,9 @@ mod test {
assert!(rescan_result.is_ok()); assert!(rescan_result.is_ok());
let rescan_result = rescan_result.unwrap(); let rescan_result = rescan_result.unwrap();
assert_eq!(rescan_result.len(), 3); assert_eq!(rescan_result.len(), 3);
rescan_result.into_iter().for_each(|outcome| { rescan_result
assert!(outcome.is_ok()); .into_iter()
let outcome = outcome.unwrap(); .for_each(|outcome| assert!(matches!(outcome, UpdatePathOutcome::Unchanged(_))));
assert!(matches!(outcome, UpdatePathOutcome::Unchanged(_)))
});
// Remove a file // Remove a file
@ -438,14 +443,14 @@ mod test {
2, 2,
rescan_result rescan_result
.iter() .iter()
.filter(|upo| matches!(upo.as_ref().unwrap(), UpdatePathOutcome::Unchanged(_))) .filter(|upo| matches!(upo, UpdatePathOutcome::Unchanged(_)))
.count() .count()
); );
assert_eq!( assert_eq!(
1, 1,
rescan_result rescan_result
.iter() .iter()
.filter(|upo| matches!(upo.as_ref().unwrap(), UpdatePathOutcome::Removed(_))) .filter(|upo| matches!(upo, UpdatePathOutcome::Removed(_)))
.count() .count()
); );
} }