improved cache tagging & purging for relations #5650
Closed
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.
This PR improves the cache tagging logic. The aim is to keep the full exactness (no stale data in the HTTP cache) but drastically reducing the amount of wrongly purged data. I open this PR as draft to receive some early feedback before progressing further and writing tests.
Problems with current implementation of cache tagging
/items/1
would purge all/items/x
, if they have a unidirectional link to a common entity. (Unidirectional here is not to be understood from a database/doctrine perspective, but from an API/serialization perspective; =property is only serialized from one side of the relationship).Changes proposed in this PR
Response change tags:
For write operations, the following tags are purged:
Post
Drop
Update
Example
/items/1#linkedParent
/items/1#linkedChildren
/items/1#embeddedParent
/items/1#embeddedChildren
/embedded_parents/4
/embedded_children/5
/embedded_children/5#embeddedGrandchildren
(in bold tag which matches the cache tags from above)
{ stringProperty: "dummy" }
The cached reponse of "GET /items/1" is still valid
{ parent: "/items/10" }
/items/1#linkedChildren
/items/10#linkedChildren
{ parent: "/items/1" }
/items/1#linkedChildren
{ dummyProperty: "dummy" }
{ embeddedParent: "/embeddedParents/4"}
/embeddedParents/4#children
{ parent: "/embedded_children/5" }
/embedded_children/5#embeddedGrandchildren
Happy to add additional examples, if the logic is not clear.
manual cache dependencies
For manual getters inside the entity, the logic doesn't know a priori, which dependencies the getter relies on. This can be manually controlled with
extraProperties['cacheDependencies']
.Is this PR will be accepted, we can also transform this into an official property.
Open points & requested feedback
AbstractItemNormalizer
? This would it make easier for users to extend or overwrite the cache tag generation with their own logic.The last point is also related towards the ability to easily extend and/or replace the cache tag system. As of now:
PurgeHttpCacheListener
.Is there a specific reason, why FOSHttpCacheBundle is not utilized? It has both
$responseTagger->addTags()
and$cacheManager->invalidateTags()
which makes it really easy, to hook into the cache system from anywhere in the logic (e.g. to invalidate additional tags in the state processor for specific operations).(A public function
addTagsFor
was for example suggested in #5086, but never implemented.)