Commit 9724e6c4 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'ci_register_job_service_one_by_one' into 'master'

Fetch build one-by-one [RUN ALL RSPEC] [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!55194
parents 03c2fbba 41d0b30f
...@@ -9,6 +9,7 @@ module Ci ...@@ -9,6 +9,7 @@ module Ci
include FromUnion include FromUnion
include TokenAuthenticatable include TokenAuthenticatable
include IgnorableColumns include IgnorableColumns
include FeatureGate
add_authentication_token_field :token, encrypted: -> { Feature.enabled?(:ci_runners_tokens_optional_encryption, default_enabled: true) ? :optional : :required } add_authentication_token_field :token, encrypted: -> { Feature.enabled?(:ci_runners_tokens_optional_encryption, default_enabled: true) ? :optional : :required }
......
...@@ -23,36 +23,11 @@ module Ci ...@@ -23,36 +23,11 @@ module Ci
private private
# rubocop: disable CodeReuse/ActiveRecord
def process_queue(params) def process_queue(params)
builds =
if runner.instance_type?
builds_for_shared_runner
elsif runner.group_type?
builds_for_group_runner
else
builds_for_project_runner
end
# pick builds that does not have other tags than runner's one
builds = builds.matches_tag_ids(runner.tags.ids)
# pick builds that have at least one tag
unless runner.run_untagged?
builds = builds.with_any_tags
end
# pick builds that older than specified age
if params.key?(:job_age)
builds = builds.queued_before(params[:job_age].seconds.ago)
end
@metrics.observe_queue_size(-> { builds.to_a.size })
valid = true valid = true
depth = 0 depth = 0
builds.each do |build| each_build(params) do |build|
depth += 1 depth += 1
@metrics.increment_queue_operation(:queue_iteration) @metrics.increment_queue_operation(:queue_iteration)
...@@ -78,9 +53,53 @@ module Ci ...@@ -78,9 +53,53 @@ module Ci
Result.new(nil, nil, valid) Result.new(nil, nil, valid)
end end
# rubocop: disable CodeReuse/ActiveRecord
def each_build(params, &blk)
builds =
if runner.instance_type?
builds_for_shared_runner
elsif runner.group_type?
builds_for_group_runner
else
builds_for_project_runner
end
# pick builds that does not have other tags than runner's one
builds = builds.matches_tag_ids(runner.tags.ids)
# pick builds that have at least one tag
unless runner.run_untagged?
builds = builds.with_any_tags
end
# pick builds that older than specified age
if params.key?(:job_age)
builds = builds.queued_before(params[:job_age].seconds.ago)
end
if Feature.enabled?(:ci_register_job_service_one_by_one, runner)
build_ids = builds.pluck(:id)
@metrics.observe_queue_size(-> { build_ids.size })
build_ids.each do |build_id|
yield Ci::Build.find(build_id)
end
else
@metrics.observe_queue_size(-> { builds.to_a.size })
builds.each(&blk)
end
end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def process_build(build, params) def process_build(build, params)
unless build.pending?
@metrics.increment_queue_operation(:build_not_pending)
return
end
if runner.can_pick?(build) if runner.can_pick?(build)
@metrics.increment_queue_operation(:build_can_pick) @metrics.increment_queue_operation(:build_can_pick)
else else
......
---
title: Fetch build one-by-one
merge_request: 55194
author:
type: performance
---
name: ci_register_job_service_one_by_one
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55194
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/323177
milestone: '13.10'
type: development
group: group::memory
default_enabled: false
...@@ -19,6 +19,7 @@ module Gitlab ...@@ -19,6 +19,7 @@ module Gitlab
OPERATION_COUNTERS = [ OPERATION_COUNTERS = [
:build_can_pick, :build_can_pick,
:build_not_pick, :build_not_pick,
:build_not_pending,
:build_conflict_lock, :build_conflict_lock,
:build_conflict_exception, :build_conflict_exception,
:build_conflict_transition, :build_conflict_transition,
......
...@@ -13,6 +13,7 @@ module Ci ...@@ -13,6 +13,7 @@ module Ci
let!(:pending_job) { create(:ci_build, pipeline: pipeline) } let!(:pending_job) { create(:ci_build, pipeline: pipeline) }
describe '#execute' do describe '#execute' do
shared_examples 'handles runner assignment' do
context 'runner follow tag list' do context 'runner follow tag list' do
it "picks build with the same tag" do it "picks build with the same tag" do
pending_job.update!(tag_list: ["linux"]) pending_job.update!(tag_list: ["linux"])
...@@ -581,6 +582,47 @@ module Ci ...@@ -581,6 +582,47 @@ module Ci
expect(pending_job).to be_running expect(pending_job).to be_running
end end
end end
context 'when only some builds can be matched by runner' do
let!(:specific_runner) { create(:ci_runner, :project, projects: [project], tag_list: %w[matching]) }
let!(:pending_job) { create(:ci_build, pipeline: pipeline, tag_list: %w[matching]) }
before do
# create additional matching and non-matching jobs
create_list(:ci_build, 2, pipeline: pipeline, tag_list: %w[matching])
create(:ci_build, pipeline: pipeline, tag_list: %w[non-matching])
end
it "observes queue size of only matching jobs" do
# pending_job + 2 x matching ones
expect(Gitlab::Ci::Queue::Metrics.queue_size_total).to receive(:observe).with({}, 3)
expect(execute(specific_runner)).to eq(pending_job)
end
end
end
context 'when ci_register_job_service_one_by_one is enabled' do
before do
stub_feature_flags(ci_register_job_service_one_by_one: true)
end
it 'picks builds one-by-one' do
expect(Ci::Build).to receive(:find).with(pending_job.id).and_call_original
expect(execute(specific_runner)).to eq(pending_job)
end
include_examples 'handles runner assignment'
end
context 'when ci_register_job_service_one_by_one is disabled' do
before do
stub_feature_flags(ci_register_job_service_one_by_one: false)
end
include_examples 'handles runner assignment'
end
end end
describe '#register_success' do describe '#register_success' do
......
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