diff --git a/src/Stache/Stores/Store.php b/src/Stache/Stores/Store.php index ee31e4236a9..c9a21e91fe5 100644 --- a/src/Stache/Stores/Store.php +++ b/src/Stache/Stores/Store.php @@ -406,8 +406,8 @@ public function clear() app('stache.indexes')->forget("{$this->key()}.{$index->name()}"); }); - $this->usedIndexes = collect(); - Stache::cacheStore()->forget($this->indexUsageCacheKey()); + // Which indexes queries use is kept. It's what tells the next warm to build them, + // rather than leaving the first requests to build each one from every item. $this->clearCachedPaths(); diff --git a/tests/Stache/StoreTest.php b/tests/Stache/StoreTest.php index 503b5b08c05..a95548bf03d 100644 --- a/tests/Stache/StoreTest.php +++ b/tests/Stache/StoreTest.php @@ -125,6 +125,39 @@ public function index_usage_cached_by_another_process_is_kept() $this->assertEquals(['path', 'site', 'uri'], Cache::get($cacheKey)); } + + #[Test] + public function clearing_keeps_which_indexes_are_used_so_the_next_warm_builds_them() + { + $cacheKey = "stache::indexes::{$this->store->key()}::_indexes"; + + $this->store->cacheIndexUsage('title'); + + $this->store->clear(); + + $this->assertEquals(['title'], Cache::get($cacheKey)); + $this->assertTrue($this->store->indexes()->has('title')); + + // A process that starts after the clear, as the one that warms usually is. + $this->assertTrue((new TestStore)->indexes()->has('title')); + } + + #[Test] + public function an_index_used_again_after_clearing_is_still_recorded() + { + // Asset containers are cleared on every request when the watcher is on, and use + // their path index straight after. See https://github.com/statamic/cms/issues/3476 + $cacheKey = "stache::indexes::{$this->store->key()}::_indexes"; + + $this->store->cacheIndexUsage('path'); + + $this->store->clear(); + + $this->store->cacheIndexUsage('path'); + + $this->assertEquals(['path'], Cache::get($cacheKey)); + $this->assertTrue((new TestStore)->indexes()->has('path')); + } } class TestStore extends Store