Skip to content

Commit 91e0466

Browse files
committed
try to make the local archive-index-write more durable
1 parent 76793fe commit 91e0466

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

src/storage/mod.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,7 @@ use std::{
4141
atomic::{AtomicU64, Ordering},
4242
},
4343
};
44-
use tokio::{
45-
io::{AsyncRead, AsyncWriteExt},
46-
runtime,
47-
sync::RwLock,
48-
};
44+
use tokio::{io::AsyncRead, runtime, sync::RwLock};
4945
use tracing::{error, info, info_span, instrument, trace, warn};
5046
use tracing_futures::Instrument as _;
5147
use walkdir::WalkDir;
@@ -428,21 +424,35 @@ impl AsyncStorage {
428424
// remote/folder/and/x.zip.index
429425
let remote_index_path = format!("{archive_path}.{ARCHIVE_INDEX_FILE_EXTENSION}");
430426

431-
tokio::fs::create_dir_all(
432-
local_index_path
433-
.parent()
434-
.ok_or_else(|| anyhow!("index path without parent"))?,
435-
)
427+
let parent = local_index_path
428+
.parent()
429+
.ok_or_else(|| anyhow!("index path without parent"))?
430+
.to_path_buf();
431+
tokio::fs::create_dir_all(&parent).await?;
432+
433+
let mut temp_path = spawn_blocking({
434+
// this creates the tempfile and directly drops it again,
435+
// just to return a valid temp-path.
436+
// This could be optimized.
437+
let folder = self.config.local_archive_cache_path.clone();
438+
move || Ok(tempfile::NamedTempFile::new_in(&folder)?.into_temp_path())
439+
})
436440
.await?;
437441

438-
{
439-
let mut file = tokio::fs::File::create(&local_index_path).await?;
440-
let mut stream = self.get_stream(&remote_index_path).await?.content;
442+
let mut file = tokio::fs::File::create(&temp_path).await?;
443+
let mut stream = self.get_stream(&remote_index_path).await?.content;
444+
tokio::io::copy(&mut stream, &mut file).await?;
445+
file.sync_all().await?;
441446

442-
tokio::io::copy(&mut stream, &mut file).await?;
447+
temp_path.disable_cleanup(true);
448+
tokio::fs::rename(&temp_path, &local_index_path).await?;
443449

444-
file.flush().await?;
445-
}
450+
// fsync parent dir to make rename durable (blocking)
451+
spawn_blocking(move || {
452+
let dir = std::fs::File::open(parent)?;
453+
dir.sync_all().map_err(Into::into)
454+
})
455+
.await?;
446456
}
447457

448458
_read_guard = _write_guard.downgrade();

0 commit comments

Comments
 (0)