Commit 1be0fefa authored by Nick Thomas's avatar Nick Thomas

Merge branch 'fix-forward-deployment-worker-dead-lock' into 'master'

Fix Forward Deployment Worker causes deadlock

See merge request gitlab-org/gitlab!58861
parents 0b1debff a88461c6
...@@ -323,7 +323,7 @@ module Ci ...@@ -323,7 +323,7 @@ module Ci
end end
end end
before_transition any => [:failed] do |build| after_transition any => [:failed] do |build|
next unless build.project next unless build.project
next unless build.deployment next unless build.deployment
......
---
title: Fix Forward Deployment Worker causes deadlock
merge_request: 58861
author:
type: fixed
...@@ -1135,6 +1135,8 @@ RSpec.describe Ci::Build do ...@@ -1135,6 +1135,8 @@ RSpec.describe Ci::Build do
end end
describe 'state transition as a deployable' do describe 'state transition as a deployable' do
subject { build.send(event) }
let!(:build) { create(:ci_build, :with_deployment, :start_review_app, project: project, pipeline: pipeline) } let!(:build) { create(:ci_build, :with_deployment, :start_review_app, project: project, pipeline: pipeline) }
let(:deployment) { build.deployment } let(:deployment) { build.deployment }
let(:environment) { deployment.environment } let(:environment) { deployment.environment }
...@@ -1149,54 +1151,78 @@ RSpec.describe Ci::Build do ...@@ -1149,54 +1151,78 @@ RSpec.describe Ci::Build do
expect(environment.name).to eq('review/master') expect(environment.name).to eq('review/master')
end end
context 'when transits to running' do shared_examples_for 'avoid deadlock' do
before do it 'executes UPDATE in the right order' do
build.run! recorded = ActiveRecord::QueryRecorder.new { subject }
index_for_build = recorded.log.index { |l| l.include?("UPDATE \"ci_builds\"") }
index_for_deployment = recorded.log.index { |l| l.include?("UPDATE \"deployments\"") }
expect(index_for_build).to be < index_for_deployment
end end
end
context 'when transits to running' do
let(:event) { :run! }
it_behaves_like 'avoid deadlock'
it 'transits deployment status to running' do it 'transits deployment status to running' do
subject
expect(deployment).to be_running expect(deployment).to be_running
end end
end end
context 'when transits to success' do context 'when transits to success' do
let(:event) { :success! }
before do before do
allow(Deployments::UpdateEnvironmentWorker).to receive(:perform_async) allow(Deployments::UpdateEnvironmentWorker).to receive(:perform_async)
allow(Deployments::ExecuteHooksWorker).to receive(:perform_async) allow(Deployments::ExecuteHooksWorker).to receive(:perform_async)
build.success!
end end
it_behaves_like 'avoid deadlock'
it 'transits deployment status to success' do it 'transits deployment status to success' do
subject
expect(deployment).to be_success expect(deployment).to be_success
end end
end end
context 'when transits to failed' do context 'when transits to failed' do
before do let(:event) { :drop! }
build.drop!
end it_behaves_like 'avoid deadlock'
it 'transits deployment status to failed' do it 'transits deployment status to failed' do
subject
expect(deployment).to be_failed expect(deployment).to be_failed
end end
end end
context 'when transits to skipped' do context 'when transits to skipped' do
before do let(:event) { :skip! }
build.skip!
end it_behaves_like 'avoid deadlock'
it 'transits deployment status to skipped' do it 'transits deployment status to skipped' do
subject
expect(deployment).to be_skipped expect(deployment).to be_skipped
end end
end end
context 'when transits to canceled' do context 'when transits to canceled' do
before do let(:event) { :cancel! }
build.cancel!
end it_behaves_like 'avoid deadlock'
it 'transits deployment status to canceled' do it 'transits deployment status to canceled' do
subject
expect(deployment).to be_canceled expect(deployment).to be_canceled
end end
end 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