From a7d75d0b601437a9fd96d879ebc060280b71d0a0 Mon Sep 17 00:00:00 2001 From: Marius Bobin <mbobin@gitlab.com> Date: Tue, 24 Aug 2021 19:41:02 +0300 Subject: [PATCH] Update the query that looks for stuck pending jobs We have around 500 CI jobs that are in the pending state but can't be picked by the runners. --- app/models/commit_status.rb | 3 ++- app/workers/stuck_ci_jobs_worker.rb | 14 ++++++++++++-- .../ci_new_query_for_pending_stuck_jobs.yml | 8 ++++++++ spec/models/commit_status_spec.rb | 9 +++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 config/feature_flags/development/ci_new_query_for_pending_stuck_jobs.yml diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 8ff5a6f38e211..8dd650751bf0b 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -58,7 +58,8 @@ class CommitStatus < Ci::ApplicationRecord scope :in_pipelines, ->(pipelines) { where(pipeline: pipelines) } scope :eager_load_pipeline, -> { eager_load(:pipeline, project: { namespace: :route }) } scope :with_pipeline, -> { joins(:pipeline) } - scope :updated_at_before, ->(date) { where('updated_at < ?', date) } + scope :updated_at_before, ->(date) { where('ci_builds.updated_at < ?', date) } + scope :created_at_before, ->(date) { where('ci_builds.created_at < ?', date) } scope :updated_before, ->(lookback:, timeout:) { where('(ci_builds.created_at BETWEEN ? AND ?) AND (ci_builds.updated_at BETWEEN ? AND ?)', lookback, timeout, lookback, timeout) } diff --git a/app/workers/stuck_ci_jobs_worker.rb b/app/workers/stuck_ci_jobs_worker.rb index 5723380a3f32e..04bef83040f7a 100644 --- a/app/workers/stuck_ci_jobs_worker.rb +++ b/app/workers/stuck_ci_jobs_worker.rb @@ -26,14 +26,14 @@ def perform drop(running_timed_out_builds, failure_reason: :stuck_or_timeout_failure) drop( - Ci::Build.pending.updated_before(lookback: BUILD_LOOKBACK.ago, timeout: BUILD_PENDING_OUTDATED_TIMEOUT.ago), + pending_builds(BUILD_PENDING_OUTDATED_TIMEOUT.ago), failure_reason: :stuck_or_timeout_failure ) drop(scheduled_timed_out_builds, failure_reason: :stale_schedule) drop_stuck( - Ci::Build.pending.updated_before(lookback: BUILD_LOOKBACK.ago, timeout: BUILD_PENDING_STUCK_TIMEOUT.ago), + pending_builds(BUILD_PENDING_STUCK_TIMEOUT.ago), failure_reason: :stuck_or_timeout_failure ) @@ -42,6 +42,16 @@ def perform private + # rubocop: disable CodeReuse/ActiveRecord + def pending_builds(timeout) + if Feature.enabled?(:ci_new_query_for_pending_stuck_jobs) + Ci::Build.pending.created_at_before(timeout).updated_at_before(timeout).order(created_at: :asc, project_id: :asc) + else + Ci::Build.pending.updated_before(lookback: BUILD_LOOKBACK.ago, timeout: timeout) + end + end + # rubocop: enable CodeReuse/ActiveRecord + def scheduled_timed_out_builds Ci::Build.where(status: :scheduled).where( # rubocop: disable CodeReuse/ActiveRecord 'ci_builds.scheduled_at IS NOT NULL AND ci_builds.scheduled_at < ?', diff --git a/config/feature_flags/development/ci_new_query_for_pending_stuck_jobs.yml b/config/feature_flags/development/ci_new_query_for_pending_stuck_jobs.yml new file mode 100644 index 0000000000000..5e63330d01d4d --- /dev/null +++ b/config/feature_flags/development/ci_new_query_for_pending_stuck_jobs.yml @@ -0,0 +1,8 @@ +--- +name: ci_new_query_for_pending_stuck_jobs +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68880 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339322 +milestone: '14.3' +type: development +group: group::pipeline execution +default_enabled: false diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index a951af4cc4f61..7134a387e6518 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -88,6 +88,15 @@ def create_status(**opts) end end + describe '.created_at_before' do + it 'finds the relevant records' do + status = create(:commit_status, created_at: 1.day.ago, project: project) + create(:commit_status, created_at: 1.day.since, project: project) + + expect(described_class.created_at_before(Time.current)).to eq([status]) + end + end + describe '.updated_before' do let!(:lookback) { 5.days.ago } let!(:timeout) { 1.day.ago } -- GitLab