Sign in or sign up before continuing. Don't have an account yet? Register now to get started.
Register now
Spike: Is it possible to delete project_authorizations scoped to the deleted group?
<!--IssueSummary start--> <details> <summary> Everyone can contribute. [Help move this issue forward](https://handbook.gitlab.com/handbook/marketing/developer-relations/contributor-success/community-contributors-workflows/#contributor-links) while earning points, leveling up and collecting rewards. </summary> - [Close this issue](https://contributors.gitlab.com/manage-issue?action=close&projectId=278964&issueIid=554451) </details> <!--IssueSummary end--> When a group is deleted and it has been shared with another group or project, [an instance of `UserProjectAccessChangedService` is executed](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/groups/destroy_service.rb#L44) for all members of the group. This becomes a problem when the deleted group has a lot of members (thousands) because it enqueues one `AuthorizedProjectsWorker` job for each user. Each job basically tries to compute the expected `project_authorizations` records ([Gitlab::ProjectAuthorizations](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/project_authorizations.rb)) that should exist for the user and then figures out if there are records that should be deleted as a result of the group being deleted. So, if the user had access to 1_000 projects from 1_000 different groups and 1 group was deleted the worker would essentially waste time trying to compute the expected records for 999 projects instead of just 1. ### Why does `AuthorizedProjectWorker` do this? To illustrate, ``` Group G1 <- User U `-> Project P1 Group G2 `-> Project P2 - Group G1 is invited to Group G2 project_authorizations: [U, P1] [U, P2] ``` When group `G1` is deleted project `P1` would also be deleted which results to the `project_authorization` record `[U, P1]` to automatically get deleted c/o the `project_id` foreign key. However, the record `[U, P2]` would remain and that's where the call to `UserProjectAccessChangedService` come in. It's probable that `G1` has already been deleted from the DB before the enqueued `AuthorizedProjectsWorker` job finishes which means `group|project_group_links` and `members` pointing to `G1` would have already been deleted (c/o FKs). Without these records, it's impossible to trace which `project_authorization` records were created because of the user's membership to the deleted group. The only way to know which records need to be deleted is to compute a set of records should exist and delete all existing records that are not in that set. Another problem is illustrated with the following scenario ``` Group G1 <- User U `-> Project P1 Group G2 `-> Project P2 - Group G1 is invited to Group G2 - User U is invited to Project P2 project_authorizations: [U, P1] [U, P2] ``` `[U, P2]` in this case has two "sources"–user `U`'s membership to `G1` and membership to `P2`. So, if we're just looking at `members` and `group_group_links` records associated to `G1` we can determine that `[U, P2]` should probably need to be deleted but that conclusion would be wrong. ## Ideas to validate 1. Delete `project_authorizations` records for the user created as a result of their membership to the a deleted group **before** records required for computation are deleted (`group|project_group_links`, `members`, etc.) 2. ...
task