diff --git a/crates/symbolicator-service/src/caching/memory.rs b/crates/symbolicator-service/src/caching/memory.rs index f279da712..1c9fe75dd 100644 --- a/crates/symbolicator-service/src/caching/memory.rs +++ b/crates/symbolicator-service/src/caching/memory.rs @@ -270,9 +270,25 @@ impl Cacher { // TODO: Not handling negative caches probably has a huge perf impact. Need to // figure out negative caches. Maybe put them in redis with a TTL? if !shared_cache_hit { - if let Ok(byteview) = &entry { - if let Some(shared_cache) = shared_cache { - shared_cache.store(name, &cache_path, byteview.clone(), CacheStoreReason::New); + if let Some(shared_cache) = shared_cache { + match &entry { + Ok(byteview) => { + shared_cache.store( + name, + &cache_path, + byteview.clone(), + CacheStoreReason::New, + ); + } + Err(CacheError::NotFound) => { + shared_cache.store( + name, + &cache_path, + ByteView::from_slice(b""), // Store an empty file to indicate source not found. + CacheStoreReason::New, + ); + } + Err(_) => {} } } } diff --git a/crates/symbolicator-service/src/caching/shared_cache/mod.rs b/crates/symbolicator-service/src/caching/shared_cache/mod.rs index 9a0f914b6..9f15a26c7 100644 --- a/crates/symbolicator-service/src/caching/shared_cache/mod.rs +++ b/crates/symbolicator-service/src/caching/shared_cache/mod.rs @@ -893,6 +893,42 @@ mod tests { assert_eq!(buf, b""); } + #[tokio::test] + async fn test_filesystem_empty_store() { + symbolicator_test::setup(); + let dir = symbolicator_test::tempdir(); + + let key = "global/some_item"; + + let cfg = SharedCacheConfig { + max_concurrent_uploads: 10, + max_upload_queue_size: 10, + backend: SharedCacheBackendConfig::Filesystem(FilesystemSharedCacheConfig { + path: dir.path().to_path_buf(), + }), + }; + let svc = SharedCacheService::new(Some(cfg), tokio::runtime::Handle::current()); + let svc = wait_init(&svc).await; + + let recv = svc.store( + CacheName::Objects, + key, + ByteView::from_slice(b""), + CacheStoreReason::New, + ); + // Wait for storing to complete. + recv.await.unwrap(); + + let temp_file = NamedTempFile::new_in(&dir).unwrap(); + let file = File::from_std(temp_file.reopen().unwrap()); + + let ret = svc.fetch(CacheName::Objects, key, file).await; + assert!(ret); // We find something. + + let buf = std::fs::read(temp_file).unwrap(); + assert_eq!(buf, b""); // But the thing we find is an empty file. + } + #[tokio::test] async fn test_filesystem_store() { symbolicator_test::setup();