This fixes a high frequency N+1 issue:
`RoutableActions#find_routable!` is used across many controllers to
retrieve e.g. the Project or Namespace by path. The `#find_routable!`
method calls `#ensure_canonical_path` which in turn retrieves
`#full_path` from the given Routable.
This in turn triggers a lookup on `routes`, leading to a high frequency
of these queries:
```sql
SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND
"routes"."source_type" = $2 LIMIT $3
```
This is unnecessary as we already join `routes` in
`Routable#find_by_full_path` anyways.
Add columns to store project creation settings
Add project creation level column in groups
and default project creation column in application settings
Remove obsolete line from schema
Update migration with project_creation_level column existence check
Rename migrations to avoid conflicts
Update migration methods
Update migration method
* Changed name of delete_user_service and worker to destroy
* Move and change delete_group_service to Groups::DestroyService
* Rename Notes::DeleteService to Notes::DestroyService
This adds counters for build artifacts and LFS objects, and moves
the preexisting repository_size and commit_count from the projects
table into a new project_statistics table.
The counters are displayed in the administration area for projects
and groups, and also available through the API for admins (on */all)
and normal users (on */owned)
The statistics are updated through ProjectCacheWorker, which can now
do more granular updates with the new :statistics argument.
* add parent_id field to namespaces table to store relation with nested groups
* create routes table to keep information about full path of every group and project
* project/group lookup by full path from routes table
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
There is a race condition in DestroyGroupService now that projects are deleted asynchronously:
1. User attempts to delete group
2. DestroyGroupService iterates through all projects and schedules a Sidekiq job to delete each Project
3. DestroyGroupService destroys the Group, leaving all its projects without a namespace
4. Projects::DestroyService runs later but the can?(current_user,
:remove_project) is `false` because the user no longer has permission to
destroy projects with no namespace.
5. This leaves the project in pending_delete state with no namespace/group.
Projects without a namespace or group also adds another problem: it's not possible to destroy the container
registry tags, since container_registry_path_with_namespace is the wrong value.
The fix is to destroy the group asynchronously and to run execute directly on Projects::DestroyService.
Closes#17893