improv(zip_extract): flush files to disk

This ensures the files are fully on the disk when the operation is done.
This commit is contained in:
Vukašin Vojinović 2026-01-24 13:48:31 +01:00
parent 1963e58560
commit d9f654ffe3
3 changed files with 79 additions and 72 deletions

View file

@ -196,6 +196,29 @@ async fn copy_or_move(
.map_err(wrap_compio_spawn_error)?
}
pub async fn sync_to_disk(
written_files: Vec<PathBuf>,
target_dirs: std::collections::HashSet<PathBuf>,
) {
use futures::{StreamExt, stream};
// Sync files to disk
let file_stream = stream::iter(written_files.into_iter().map(|path| async move {
if let Ok(file) = compio::fs::OpenOptions::new().write(true).open(&path).await {
let _ = file.sync_all().await;
}
}));
file_stream.buffer_unordered(32).collect::<Vec<_>>().await;
// Sync directories to disk
let dir_stream = stream::iter(target_dirs.into_iter().map(|path| async move {
if let Ok(dir) = compio::fs::OpenOptions::new().read(true).open(&path).await {
let _ = dir.sync_all().await;
}
}));
dir_stream.buffer_unordered(16).collect::<Vec<_>>().await;
}
fn copy_unique_path(from: &Path, to: &Path) -> PathBuf {
// List of compound extensions to check
const COMPOUND_EXTENSIONS: &[&str] = &[

View file

@ -1,14 +1,13 @@
use compio::BufResult;
use compio::buf::{IntoInner, IoBuf};
use compio::io::{AsyncReadAt, AsyncWriteAt};
use futures::{StreamExt, stream};
use std::future::Future;
use std::pin::Pin;
use std::time::Instant;
use std::{cell::Cell, error::Error, fs, ops::ControlFlow, path::PathBuf, rc::Rc};
use walkdir::WalkDir;
use crate::operation::OperationError;
use crate::operation::{OperationError, sync_to_disk};
use super::{Controller, OperationSelection, ReplaceResult, copy_unique_path};
@ -203,21 +202,8 @@ impl Context {
}
}
// Sync files to disk
let file_stream = stream::iter(written_files.into_iter().map(|path| async move {
if let Ok(file) = compio::fs::OpenOptions::new().write(true).open(&path).await {
let _ = file.sync_all().await;
}
}));
file_stream.buffer_unordered(32).collect::<Vec<_>>().await;
// Sync directories to disk
let dir_stream = stream::iter(target_dirs.into_iter().map(|path| async move {
if let Ok(dir) = compio::fs::OpenOptions::new().read(true).open(&path).await {
let _ = dir.sync_all().await;
}
}));
dir_stream.buffer_unordered(16).collect::<Vec<_>>().await;
// Flush files to disk
sync_to_disk(written_files, target_dirs).await;
Ok(true)
}