Commit 4955a47c authored by Stan Hu's avatar Stan Hu
Browse files

Clean up project destruction

Instead of redirecting from the project service to the service and back to the model,
put all destruction code in the service. Also removes a possible source of failure
where run_after_commit may not destroy the project.
parent ae2d3c41
......@@ -125,7 +125,7 @@ def show
def destroy
return access_denied! unless can?(current_user, :remove_project, @project)
::Projects::DestroyService.new(@project, current_user, {}).pending_delete!
::Projects::DestroyService.new(@project, current_user, {}).async_execute
flash[:alert] = "Project '#{@project.name}' will be deleted."
redirect_to dashboard_projects_path
......
......@@ -1161,16 +1161,6 @@ def wiki
@wiki ||= ProjectWiki.new(self, self.owner)
end
def schedule_delete!(user_id, params)
# Queue this task for after the commit, so once we mark pending_delete it will run
run_after_commit do
job_id = ProjectDestroyWorker.perform_async(id, user_id, params)
Rails.logger.info("User #{user_id} scheduled destruction of project #{path_with_namespace} with job ID #{job_id}")
end
update_attribute(:pending_delete, true)
end
def running_or_pending_build_count(force: false)
Rails.cache.fetch(['projects', id, 'running_or_pending_build_count'], force: force) do
builds.running_or_pending.count(:all)
......
......@@ -18,7 +18,7 @@ def execute(user, options = {})
user.personal_projects.each do |project|
# Skip repository removal because we remove directory with namespace
# that contain all this repositories
::Projects::DestroyService.new(project, current_user, skip_repo: true).pending_delete!
::Projects::DestroyService.new(project, current_user, skip_repo: true).async_execute
end
user.destroy
......
......@@ -9,7 +9,7 @@ def execute
group.projects.each do |project|
# Skip repository removal because we remove directory with namespace
# that contain all this repositories
::Projects::DestroyService.new(project, current_user, skip_repo: true).pending_delete!
::Projects::DestroyService.new(project, current_user, skip_repo: true).async_execute
end
group.destroy
......
......@@ -6,8 +6,12 @@ class DestroyError < StandardError; end
DELETED_FLAG = '+deleted'
def pending_delete!
project.schedule_delete!(current_user.id, params)
def async_execute
project.transaction do
project.update_attribute(:pending_delete, true)
job_id = ProjectDestroyWorker.perform_async(project.id, current_user.id, params)
Rails.logger.info("User #{current_user.id} scheduled destruction of project #{project.path_with_namespace} with job ID #{job_id}")
end
end
def execute
......
......@@ -323,7 +323,7 @@ def map_public_to_visibility_level(attrs)
# DELETE /projects/:id
delete ":id" do
authorize! :remove_project, user_project
::Projects::DestroyService.new(user_project, current_user, {}).pending_delete!
::Projects::DestroyService.new(user_project, current_user, {}).async_execute
end
# Mark this project as forked from another
......
......@@ -38,7 +38,7 @@
end
it "project_destroy hook" do
Projects::DestroyService.new(project, user, {}).pending_delete!
Projects::DestroyService.new(project, user, {}).async_execute
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /project_destroy/,
......
......@@ -15,7 +15,7 @@
end
it 'will delete the project in the near future' do
expect_any_instance_of(Projects::DestroyService).to receive(:pending_delete!).once
expect_any_instance_of(Projects::DestroyService).to receive(:async_execute).once
DeleteUserService.new(current_user).execute(user)
end
......
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