feat(offline_cache): enforce cache size limit on new track downloads
Pre-flight check_cache_limit reads the current total_size_bytes and returns an informative error if the cache is already at or over the configured limit. Wired into v2_cache_track_for_offline (single) and v2_cache_tracks_batch_for_offline (batch). Re-download paths are not gated since they target tracks already counted toward the total. The check intentionally does not predict the new track's size; preventing cache from growing further once at the limit is enough for v1. cc
This commit is contained in:
2 files changed
+44
No files matched your search
@@ -923,8 +923,13 @@ pub async fn v2_cache_track_for_offline(
|
||||
let file_path = cache_state.track_file_path(track_id, "flac");
|
||||
let file_path_str = file_path.to_string_lossy().to_string();
|
||||
{
|
||||
let limit_bytes = *cache_state.limit_bytes.lock().await;
|
||||
let guard = cache_state.db.lock().await;
|
||||
let db = guard.as_ref().ok_or("No active session - please log in")?;
|
||||
// Pre-flight: refuse new downloads when the cache is already at or
|
||||
// above the configured limit (Fix #5d).
|
||||
let cache_root = std::path::PathBuf::from(cache_state.get_cache_path());
|
||||
crate::offline_cache::maintenance::check_cache_limit(db, &cache_root, limit_bytes)?;
|
||||
db.insert_track(&track_info, &file_path_str)?;
|
||||
}
|
||||
|
||||
@@ -995,8 +1000,14 @@ pub async fn v2_cache_tracks_batch_for_offline(
|
||||
|
||||
// Single transactional batch insert
|
||||
{
|
||||
let limit_bytes = *cache_state.limit_bytes.lock().await;
|
||||
let guard = cache_state.db.lock().await;
|
||||
let db = guard.as_ref().ok_or("No active session - please log in")?;
|
||||
// Pre-flight: refuse new batch downloads when the cache is already at
|
||||
// or above the configured limit (Fix #5d). One check covers the whole
|
||||
// batch; this is intentionally simple and does not predict batch size.
|
||||
let cache_root = std::path::PathBuf::from(cache_state.get_cache_path());
|
||||
crate::offline_cache::maintenance::check_cache_limit(db, &cache_root, limit_bytes)?;
|
||||
let refs: Vec<(&crate::offline_cache::TrackCacheInfo, String)> = batch
|
||||
.iter()
|
||||
.map(|(info, path)| (info, path.clone()))
|
||||
|
||||
@@ -41,6 +41,39 @@ pub fn remove_album_cached_tracks(
|
||||
})
|
||||
}
|
||||
|
||||
/// Pre-flight cache-limit check executed before queuing new downloads.
|
||||
///
|
||||
/// Returns `Ok(())` when:
|
||||
/// - `limit_bytes` is `None` (no limit configured); OR
|
||||
/// - the current `total_size_bytes` from the cache stats is strictly below the
|
||||
/// configured limit.
|
||||
///
|
||||
/// Returns `Err(message)` when the cache has already met or exceeded the
|
||||
/// configured limit. The message is suitable for surfacing to end users via a
|
||||
/// toast.
|
||||
///
|
||||
/// Intentionally simple: it does not predict the new track's size. Sufficient
|
||||
/// for v1 — the user gets feedback the moment they hit the limit and can free
|
||||
/// space or raise the limit through the offline cache manager.
|
||||
pub fn check_cache_limit(
|
||||
db: &OfflineCacheDb,
|
||||
offline_root: &Path,
|
||||
limit_bytes: Option<u64>,
|
||||
) -> Result<(), String> {
|
||||
let limit = match limit_bytes {
|
||||
Some(value) => value,
|
||||
None => return Ok(()),
|
||||
};
|
||||
let stats = db.get_stats(&offline_root.to_string_lossy(), Some(limit))?;
|
||||
if stats.total_size_bytes >= limit {
|
||||
return Err(
|
||||
"Offline cache limit reached. Free space or raise the limit in the offline cache manager."
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Filters tracks targeted by re-download: skip in-flight Downloading,
|
||||
/// optionally restrict to Failed only.
|
||||
pub fn select_redownload_targets(
|
||||
|
||||
Reference in new issue
Block a user