Task/dogpile orm event invalidation - #3033
Conversation
Implement a basic ORM event driven invalidation strategy for service keys. Listeners are attached to the sqlalchemy session `after_flush`, `after_commit` and `after_rollback` events which will invalidate service cache keys under the following conditions - `service` entity is updated/deleted - `service_permissions` are updated - `service_user` list is added to, updated, or removed from (cherry picked from commit 2744298)
(cherry picked from commit 688adfc)
(cherry picked from commit dc74a95)
- Rename service_cache_events -> cache_events - Add cache_invalidation_registry to centralize and define entity -> cache key relationships - Entity id collection is now generic and only collects ids of entities that exist in the cache_invalidation_registry - _invalidate_cache_after_commit now references the registry to determine which cache key groups should be invalidated - Register cache_orm_events on application startup
| for namespace, entity_id in invalidations: | ||
| try: | ||
| invalidate_group_keys(namespace, entity_id) | ||
| except Exception: |
|
Original convo from here I am concerned that this approach (and the other PR too but maybe slightly less) might be difficult to scale, i.e. every time a developer wants certain cache to be added, they would have to make sure proper specific events fire, and that these are for service IDs, is that right? And when we want to add a cache specific to users, and templates, and keys, and etc.. we'd have also to add specific glue code for these? The cache isn't generic enough to handle these automatically? Response
With the current implementation, yes this would have to be done to accommodate more than just the service entity.
The baseline dogpile library isn't smart enough to graph and evaluate the potential entity relationships and invalidate corresponding keys on it's own. One possibility to facilitate a generic implementation would be to leverage a registry that centrally stores (and therefore documents) entity <-> cache key dependency metadata. Then developers only need to update the registry when new relationships are added in the DB, or additional DAO methods are marked via annotation to leverage dogpile. Something like this:
The two new things here would be the
I've taken the liberty to implement the beginnings of such an approach and it is now included in this PR. |

Summary | Résumé
This PR experimentally implements an ORM-event driven invalidation strategy for
Serviceentities. Rather than calling an explicitinvalidate_service_cache_keys()function on every path that mutates service and service related data; we instead listen toafter_flush,after_commit, andafter_rollbacksqlalchemy session events, weaving cache invalidation calls into that process. (similar in nature to aspect oriented programming)This nets us:
How it works
TODO
Related Issues | Cartes liées
Test instructions | Instructions pour tester la modification
Release Instructions | Instructions pour le déploiement
None.
Reviewer checklist | Liste de vérification du réviseur