Sign in or sign up before continuing. Don't have an account yet? Register now to get started.
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