Commit 637894de authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'fix-ci-requests-concurrency' into 'master'

Fix CI requests concurrency

See merge request !8760
parents 6cfe60df 31be74c7
...@@ -6,6 +6,8 @@ module Ci ...@@ -6,6 +6,8 @@ module Ci
attr_reader :runner attr_reader :runner
Result = Struct.new(:build, :valid?)
def initialize(runner) def initialize(runner)
@runner = runner @runner = runner
end end
...@@ -29,10 +31,10 @@ module Ci ...@@ -29,10 +31,10 @@ module Ci
build.run! build.run!
end end
build Result.new(build, true)
rescue StateMachines::InvalidTransition, ActiveRecord::StaleObjectError rescue StateMachines::InvalidTransition, ActiveRecord::StaleObjectError
nil Result.new(build, false)
end end
private private
......
---
title: 'Fix CI requests concurrency for newer runners that prevents from picking pending builds (from 1.9.0-rc5)'
merge_request: 8760
...@@ -18,18 +18,20 @@ module Ci ...@@ -18,18 +18,20 @@ module Ci
if current_runner.is_runner_queue_value_latest?(params[:last_update]) if current_runner.is_runner_queue_value_latest?(params[:last_update])
header 'X-GitLab-Last-Update', params[:last_update] header 'X-GitLab-Last-Update', params[:last_update]
Gitlab::Metrics.add_event(:build_not_found_cached)
return build_not_found! return build_not_found!
end end
new_update = current_runner.ensure_runner_queue_value new_update = current_runner.ensure_runner_queue_value
build = Ci::RegisterBuildService.new(current_runner).execute result = Ci::RegisterBuildService.new(current_runner).execute
if build if result.valid?
if result.build
Gitlab::Metrics.add_event(:build_found, Gitlab::Metrics.add_event(:build_found,
project: build.project.path_with_namespace) project: result.build.project.path_with_namespace)
present build, with: Entities::BuildDetails present result.build, with: Entities::BuildDetails
else else
Gitlab::Metrics.add_event(:build_not_found) Gitlab::Metrics.add_event(:build_not_found)
...@@ -37,6 +39,11 @@ module Ci ...@@ -37,6 +39,11 @@ module Ci
build_not_found! build_not_found!
end end
else
# We received build that is invalid due to concurrency conflict
Gitlab::Metrics.add_event(:build_invalid)
conflict!
end
end end
# Update an existing build - Runners only # Update an existing build - Runners only
......
...@@ -91,6 +91,20 @@ describe Ci::API::Builds do ...@@ -91,6 +91,20 @@ describe Ci::API::Builds do
expect { register_builds }.to change { runner.reload.contacted_at } expect { register_builds }.to change { runner.reload.contacted_at }
end end
context 'when concurrently updating build' do
before do
expect_any_instance_of(Ci::Build).to receive(:run!).
and_raise(ActiveRecord::StaleObjectError.new(nil, nil))
end
it 'returns a conflict' do
register_builds info: { platform: :darwin }
expect(response).to have_http_status(409)
expect(response.headers).not_to have_key('X-GitLab-Last-Update')
end
end
context 'registry credentials' do context 'registry credentials' do
let(:registry_credentials) do let(:registry_credentials) do
{ 'type' => 'registry', { 'type' => 'registry',
......
...@@ -171,7 +171,7 @@ module Ci ...@@ -171,7 +171,7 @@ module Ci
end end
def execute(runner) def execute(runner)
described_class.new(runner).execute described_class.new(runner).execute.build
end end
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