Skip to content

Improve lookup of access level for groups

Felipe Cardozo requested to merge issue_327901_2 into master

What does this MR do and why?

Improve group authorization check performance for big hierarchies taking advantage of traversal ids.

This changes how we cache group authorizations on RequestStore creating the cache key based on a group root ancestor id, storing all direct group authorization of a hierarchy for users using a single query.

Consider trying to fetch epics for the following group hierarchy:

 graph TD;
   1-->2;
   1-->3;

How it works now

What we are doing now is creating a cache key for each group of the hierarchy and checking authorizations for each of them. The values on RequestStore will end up like:

"max_member_access_for_users:Group:1" = [
  {user_1_id => 30}, { user_2_id => 20 }
] 

"max_member_access_for_users:Group:2" = [
  {user_1_id => 30}, { user_2_id => 20 }
] 

"max_member_access_for_users:Group:3" = [
  {user_1_id => 30}, { user_2_id => 20 }
] 

When looking for Group 1 access level we only build the cache for it. Now when looking for group 2 we have to perform another query and so on, giving N+1s queries.

What happens in this merge request

When trying to look for access level on any group we build the cache for the whole hierarchy with its key based on the root ancestor id, ending up with:

"max_member_access_for_users:Group:root_ancestor_id:1" = {
    user_1_id => [{ group_id: 1, access_level: 30 }],
    user_2_id => [{ group_id: 2, access_level: 20 }, { group_id: 3, access_level: 20 }]
}

After checking the authorization for group A the cache already has direct authorizations for all groups. Now when looking for authorizations of user_1 for group 2 we search in the cache if there is any authorization that includes group_2.traversal_ids:

  cached_authorizations.select do |authorization| 
    group_2.traversal_ids.include(authorization.group_id)
  end

If none is found it means user has no access to the given group. This way we can get access levels for all groups with one query.

You can see the query and plans to get direct authorizations for all groups within a hierarchy, including shared ones at $2349029, I tested this for a group with more than 50k subgroups and the speed is very decent.

How to set up and validate locally

TBD

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Felipe Cardozo

Merge request reports