Merge #1145: Remove all leftover temp files at server startup (@Silvertree2010)

# Conflicts:
#	apps/figcraft-server/src/store_tests.rs
This commit is contained in:
bflatastic
2026-10-24 09:22:54 +07:00
2 changed files with 39 additions and 1 deletions
+12 -1
View File
@@ -366,6 +366,9 @@ impl Store {
/// `None` when someone else holds the directory.
pub fn try_open(root: &Path, cfg: StoreConfig) -> Result<Option<Store>, String> {
let Some(lock) = lock(root)? else { return Ok(None) };
for name in [KEY, BLOCKED, REPORTS] {
let _ = fs::remove_file(disk::temp_of(&root.join(name)));
}
let key = load_key(root)?;
let dir = root.join(FILES);
fs::create_dir_all(&dir).map_err(|e| format!("can't create {}: {e}", dir.display()))?;
@@ -446,12 +449,20 @@ impl Store {
/// A file folder's description and links, after checking its snapshot and log. Leftover
/// temporary files (writes cut short) are removed.
fn check(&self, path: &Path) -> Result<Entry, String> {
for name in [SNAPSHOT, LOG, META, LINKS] {
for name in [SNAPSHOT, LOG, META, LINKS, USAGE] {
let tmp = disk::temp_of(&path.join(name));
if tmp.exists() {
let _ = fs::remove_file(&tmp);
}
}
if let Ok(entries) = fs::read_dir(path) {
for e in entries.flatten() {
let name = e.file_name().to_string_lossy().into_owned();
if name.starts_with("library-") && name.ends_with(".bin.tmp") {
let _ = fs::remove_file(e.path());
}
}
}
let meta: Meta = serde_json::from_slice(&disk::read_capped(&path.join(META), 1 << 20)?).map_err(|e| format!("{META} is damaged ({e})"))?;
let links: Vec<Link> =
serde_json::from_slice(&disk::read_capped(&path.join(LINKS), 16 << 20)?).map_err(|e| format!("{LINKS} is damaged ({e})"))?;
+27
View File
@@ -418,3 +418,30 @@ fn a_maxed_out_generation_does_not_wrap() {
let snap = disk::check_snapshot(&fs::read(path.join(SNAPSHOT)).unwrap()).unwrap();
assert_eq!(snap, u64::MAX);
}
}
#[test]
fn every_leftover_temporary_file_is_removed_at_startup() {
let dir = TempDir::new("leftovers");
let id = {
let mut store = Store::open(dir.path(), cfg(dir.path())).unwrap();
let id = publish(&mut store, "A").0;
store.flush();
id
};
let folder = dir.path().join(FILES).join(&id);
let leftovers = [
dir.path().join("blocked.json.tmp"),
dir.path().join("reports.json.tmp"),
dir.path().join("server.key.tmp"),
folder.join("usage.json.tmp"),
folder.join("library-1.bin.tmp"),
];
for path in &leftovers {
fs::write(path, b"half").unwrap();
}
let _store = Store::open(dir.path(), cfg(dir.path())).unwrap();
for path in &leftovers {
assert!(!path.exists(), "leftover not cleaned at startup: {}", path.display());
}
}