feat: optional keys-for-cache (KFC) support - #280
Open
erikfrerejean wants to merge 6 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Adds optional out-of-the-box support for
silverstripe-terraformers/keys-for-cache(KFC) so grid elements get reliable, auto-invalidating cache keys when the module is installed — without making it a hard dependency. It is added undersuggest, and all wiring is guarded byOnly: moduleexists.Approach
The integration is config-only — no PHP, no imports, no PHPStan stubs. KFC already applies its
CacheKeyExtensiontoDataObjectglobally, so_config/keys-for-cache.ymlonly:has_cache_key: trueonGridElement(inherited bySection/Row/Column/ContentElementand any consumer subclass);caresdownward through thehas_manyrelations (Section→Rows,Row→Columns,Column→Elements), deliberately avoiding the polymorphicParentedge. A change to any descendant transitively invalidates its ancestors' keys.Consumers cache per-section in their own templates:
<% loop $Sections %><% cached $CacheKey %>$Me<% end_cached %><% end_loop %>. We do not optSiteTreeintohas_cache_key(only classes we own).Test environment consolidation
The previous per-module
app-fluentDocker service is replaced by a singleapp-modulesenv that installs all optional modules (Fluent and KFC). Baseappstays the zero-optional-deps baseline;app-modulesis the everything-optional env. This touchescompose.yml,Makefile(make test-modules),composer.modules.json,phpunit.xml.dist(newkfcsuite), and CI. Trade-off: thekfcsuite runs with Fluent also present (the realistic combined target); the base env still proves "works with nothing optional".KFC's SS6-compatible release is
^3.0(1.x/2.x cap at framework ^5).Not included — owned-media caching (deferred)
Caching media-image edits was dropped: KFC cannot
caresabout ahas_onewhose target has no reciprocal relation, andMediaImage/VideoCustomThumbnailpoint to the sharedImageclass. Editing media via an element's CMS form re-saves the element (which does invalidate via the downwardcares); only editing an in-useImagedirectly in asset-admin is uncovered. Documented as a known limitation; a per-element owned media model that KFC can traverse is a planned separate project.Tests
New
tests/Integration/KeysForCache/suite guards: cache-key presence, transitive ancestor invalidation, cross-tree isolation, and draft/live separation. (Invalidation tests use KFC's documentedProcessedUpdatesService::flush()to defeat its per-request dedup; assertions are not weakened.)Verification (local):
OK (1199 tests, 3919 assertions)integration,functional,fluent,kfc):OK (766 tests, 2444 assertions)Docs
docs/architecture/keys-for-cache.md— what activates, thecaresgraph, the<% cached %>recipe, the Fluentglobal_keynote, the media limitation, and the per-write cost note.composer.json) while dev containers run breaks it inside the container until--force-recreate.