Commit 8a71d40e authored by Stan Hu's avatar Stan Hu

Fix race condition where a namespace would be deleted before a project was deleted

When deleting a user, the following sequence could happen:

1. Project `mygroup/myproject` is scheduled for deletion
2. The group `mygroup` is deleted
3. Sidekiq worker runs to delete `mygroup/myproject`, but the namespace and routes have
   been destroyed.

Closes #30334
parent 9fc17f6f
...@@ -20,10 +20,10 @@ module Users ...@@ -20,10 +20,10 @@ module Users
Groups::DestroyService.new(group, current_user).execute Groups::DestroyService.new(group, current_user).execute
end end
user.personal_projects.each do |project| user.personal_projects.with_deleted.each do |project|
# Skip repository removal because we remove directory with namespace # Skip repository removal because we remove directory with namespace
# that contain all this repositories # that contain all this repositories
::Projects::DestroyService.new(project, current_user, skip_repo: true).async_execute ::Projects::DestroyService.new(project, current_user, skip_repo: true).execute
end end
move_issues_to_ghost_user(user) move_issues_to_ghost_user(user)
......
---
title: Fix race condition where a namespace would be deleted before a project was
deleted
merge_request:
author:
...@@ -17,13 +17,28 @@ describe Users::DestroyService, services: true do ...@@ -17,13 +17,28 @@ describe Users::DestroyService, services: true do
expect { Namespace.with_deleted.find(user.namespace.id) }.to raise_error(ActiveRecord::RecordNotFound) expect { Namespace.with_deleted.find(user.namespace.id) }.to raise_error(ActiveRecord::RecordNotFound)
end end
it 'will delete the project in the near future' do it 'will delete the project' do
expect_any_instance_of(Projects::DestroyService).to receive(:async_execute).once expect_any_instance_of(Projects::DestroyService).to receive(:execute).once
service.execute(user) service.execute(user)
end end
end end
context 'projects in pending_delete' do
before do
project.pending_delete = true
project.save
end
it 'destroys a project in pending_delete' do
expect_any_instance_of(Projects::DestroyService).to receive(:execute).once
service.execute(user)
expect { Project.find(project.id) }.to raise_error(ActiveRecord::RecordNotFound)
end
end
context "a deleted user's issues" do context "a deleted user's issues" do
let(:project) { create(:project) } let(:project) { create(:project) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment