[Group Hierarchy] Implement cache invalidator method
For now, we take the simple approach and invalidate the namespace_descendants cache when traversal_ids change happens. The invalidation must happen synchronously in order to avoid returning stale data.
Task: implement a new class method in the Namespaces::Descendant model: expire_for(array_of_namespace_ids)
The method would invoke an UPDATE query where the namespace_descendants record for each namespace id would be marked as outdated (if exists).
Invalidation:
- Hook into the namespace destroy callback and call
Namespaces::Descendants.expire_for(traversal_ids) - Hook into the
sync_traversal_idscallback and determine the old and new traversal ids array for the changed namespace. Invoke theNamespaces::Descendants.expire_for(all_traversal_ids)
- Note 1: Depending on AR hooks can cause inconsistent records if some hierarchy updates happen outside of ActiveRecord. Ideally, we should do this in a trigger but to reduce the change radius, we take the callback based approach.
- Note 2: Only do the expiration when the
group_hierarchy_optimizationfeature flag is on. - Note 3: Listening to only namespace changes should also work for the project id cache, since each project has a namespace record.
Edited by Adam Hegyi