Prefetch nearby scene assets in the background
Some checks failed
CI / rust-skia (Rust only) (push) Has been cancelled
CI / required (push) Has been cancelled

This commit is contained in:
2026-08-23 11:06:28 +02:00
parent d85f7d22f2
commit b59bc4c3cd
12 changed files with 259 additions and 32 deletions

View File

@@ -37,3 +37,11 @@ Files: `src/grid_manager.rs`, `src/client_core.rs`.
the existing UDP asset transfer path instead of reporting a missing asset immediately.
File: `src/asset_manager.rs`.
## Deterministic persistent-asset LRU
- Successful immutable asset-cache reads explicitly refresh the file modification timestamp.
Pruning uses that timestamp as its cross-platform LRU order instead of filesystem access time,
which can be disabled or coarsened by `noatime` and `relatime` mounts.
Files: `src/asset_cache.rs`, `src/asset_pipeline_semantics.rs`.

View File

@@ -189,6 +189,10 @@ impl AssetCache {
if bytes.len() as u64 != metadata.len() {
return Err(Error::InvalidOperation);
}
// Use the modification timestamp as a portable, explicit LRU marker.
// Filesystems commonly mount with relatime/noatime, so access time is
// not reliable enough for cache eviction.
let _ = fs::File::open(path).and_then(|file| file.set_modified(SystemTime::now()));
Ok(Some(bytes))
}
@@ -353,10 +357,7 @@ impl AssetCache {
entries.push((
entry.path(),
metadata.len(),
metadata
.accessed()
.or_else(|_| metadata.modified())
.unwrap_or(UNIX_EPOCH),
metadata.modified().unwrap_or(UNIX_EPOCH),
));
}
}

View File

@@ -137,13 +137,16 @@ fn custom_cache_naming_is_used_but_cannot_escape_the_cache_directory() {
#[tokio::test]
async fn cache_pruning_reclaims_old_entries_to_below_the_limit() {
let (_client, cache, path) = fixture(12);
let first = UUID::random().unwrap();
let second = UUID::random().unwrap();
cache
.save_asset_to_cache_with_uuid_bytes(UUID::random().unwrap(), vec![1; 8])
.save_asset_to_cache_with_uuid_bytes(first, vec![1; 8])
.unwrap();
std::thread::sleep(std::time::Duration::from_millis(5));
std::thread::sleep(std::time::Duration::from_millis(20));
cache
.save_asset_to_cache_with_uuid_bytes(UUID::random().unwrap(), vec![2; 8])
.save_asset_to_cache_with_uuid_bytes(second, vec![2; 8])
.unwrap();
cache.get_cached_asset_bytes_with_uuid(first).unwrap();
cache.prune(None).await.unwrap();
let bytes: u64 = fs::read_dir(&path)
.unwrap()
@@ -152,5 +155,7 @@ async fn cache_pruning_reclaims_old_entries_to_below_the_limit() {
.map(|metadata| metadata.len())
.sum();
assert!(bytes <= 10);
assert!(path.join(first.to_string()).is_file());
assert!(!path.join(second.to_string()).exists());
fs::remove_dir_all(path).unwrap();
}