diff --git a/src/Stache/Stores/Store.php b/src/Stache/Stores/Store.php index b9b067a76a6..8216807079a 100644 --- a/src/Stache/Stores/Store.php +++ b/src/Stache/Stores/Store.php @@ -121,9 +121,13 @@ public function cacheIndexUsage($index) $indexes->push($index); - $this->usedIndexes = $indexes; + // Another process may have recorded usages since this one memoized its + // list (e.g. parallel warming), so merge with the cache rather than replace it. + $cached = collect(Stache::cacheStore()->get($key = $this->indexUsageCacheKey(), [])); - Stache::cacheStore()->put($this->indexUsageCacheKey(), $indexes->all()); + $this->usedIndexes = $cached->merge($indexes)->unique()->sort()->values(); + + Stache::cacheStore()->put($key, $this->usedIndexes->all()); } protected function indexUsageCacheKey() diff --git a/tests/Stache/StoreTest.php b/tests/Stache/StoreTest.php index 9e22f0494ba..503b5b08c05 100644 --- a/tests/Stache/StoreTest.php +++ b/tests/Stache/StoreTest.php @@ -107,6 +107,24 @@ public function it_gets_the_paths_from_the_cache_again_after_memoized_state_is_r $this->assertEquals($expected, $store->paths()); $this->assertEquals(2, $cacheHits); } + + #[Test] + public function index_usage_cached_by_another_process_is_kept() + { + // Two instances of the same store stand in for two processes warming + // the Stache in parallel. Each memoizes its own usage list, so the + // second write must merge with the cache instead of replacing it. + $cacheKey = "stache::indexes::{$this->store->key()}::_indexes"; + $other = new TestStore; + + $this->store->cacheIndexUsage('path'); + $other->cacheIndexUsage('path'); + + $this->store->cacheIndexUsage('site'); + $other->cacheIndexUsage('uri'); + + $this->assertEquals(['path', 'site', 'uri'], Cache::get($cacheKey)); + } } class TestStore extends Store