diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | base/Cargo.toml | 1 | ||||
-rw-r--r-- | base/src/cache.rs | 22 | ||||
-rw-r--r-- | import/src/lib.rs | 4 |
4 files changed, 22 insertions, 6 deletions
@@ -1350,6 +1350,7 @@ dependencies = [ "jellyclient", "jellycommon", "log", + "rand", "serde", "serde_yaml", "sha2", diff --git a/base/Cargo.toml b/base/Cargo.toml index 8109998..ec5cbe7 100644 --- a/base/Cargo.toml +++ b/base/Cargo.toml @@ -16,3 +16,4 @@ anyhow = "1.0.75" bincode = "2.0.0-rc.3" sled = "0.34.7" typed-sled = "0.2.3" +rand = "0.8.5" diff --git a/base/src/cache.rs b/base/src/cache.rs index d2d7990..e580130 100644 --- a/base/src/cache.rs +++ b/base/src/cache.rs @@ -9,11 +9,15 @@ use base64::Engine; use bincode::{Decode, Encode}; use jellycommon::AssetLocation; use log::{info, warn}; +use rand::random; use std::{ any::Any, collections::{BTreeMap, HashMap}, + fs::rename, future::Future, io::Seek, + path::PathBuf, + str::FromStr, sync::{ atomic::{AtomicUsize, Ordering}, Arc, LazyLock, RwLock, @@ -58,17 +62,23 @@ where .await .context("unable to test for cache file existance")?; if !exists { - let f = tokio::fs::File::create(location.path()) + let temp_path = + AssetLocation::Cache(PathBuf::from_str(&format!("temp-{:x}", random::<u128>()))?) + .path(); + let f = tokio::fs::File::create(&temp_path) .await .context("creating new cache file")?; match generate(f).await { Ok(()) => (), Err(e) => { warn!("cache generation failed, unlinking entry"); - tokio::fs::remove_file(location.path()).await?; + tokio::fs::remove_file(temp_path).await?; return Err(e); } } + tokio::fs::rename(temp_path, location.path()) + .await + .context("rename cache")?; } drop(_guard); Ok(location) @@ -83,15 +93,19 @@ where let _guard = CACHE_GENERATION_LOCKS[bucket % CACHE_GENERATION_BUCKET_COUNT].blocking_lock(); let exists = location.path().exists(); if !exists { - let f = std::fs::File::create(location.path()).context("creating new cache file")?; + let temp_path = + AssetLocation::Cache(PathBuf::from_str(&format!("temp-{:x}", random::<u128>()))?) + .path(); + let f = std::fs::File::create(&temp_path).context("creating new cache file")?; match generate(f) { Ok(()) => (), Err(e) => { warn!("cache generation failed, unlinking entry"); - std::fs::remove_file(location.path())?; + std::fs::remove_file(temp_path)?; return Err(e); } } + rename(temp_path, location.path()).context("rename cache")?; } drop(_guard); Ok(location) diff --git a/import/src/lib.rs b/import/src/lib.rs index 2dbf994..6a725c8 100644 --- a/import/src/lib.rs +++ b/import/src/lib.rs @@ -285,9 +285,9 @@ async fn process_source( } insert_node(&id, node)?; } else if media_path.is_file() { + let _permit = SEM_IMPORT.acquire().await.unwrap(); let location_path = location.path(); let metadata = { - let _permit = SEM_IMPORT.acquire().await.unwrap(); spawn_blocking(move || { cache_memory( &["mkv-probe", location.path().to_str().unwrap()], @@ -365,7 +365,7 @@ async fn process_source( ); } } - + drop(_permit); insert_node(&id, node)?; } else { warn!("non file/dir import ignored: {media_path:?}") |