From e8d2c2579383897a1dd7f9debd359abe8ae8373d Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 20 Jul 2021 09:55:51 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-1-stable-ee --- app/services/ci/register_job_service.rb | 86 +++++++-------------------------- 1 file changed, 17 insertions(+), 69 deletions(-) (limited to 'app/services/ci/register_job_service.rb') diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb index 6280bf4c986..dc046e1d164 100644 --- a/app/services/ci/register_job_service.rb +++ b/app/services/ci/register_job_service.rb @@ -103,35 +103,40 @@ module Ci # rubocop: disable CodeReuse/ActiveRecord def each_build(params, &blk) - builds = + queue = ::Ci::Queue::BuildQueueService.new(runner) + + builds = begin if runner.instance_type? - builds_for_shared_runner + queue.builds_for_shared_runner elsif runner.group_type? - builds_for_group_runner + queue.builds_for_group_runner else - builds_for_project_runner + queue.builds_for_project_runner end + end + + if runner.ref_protected? + builds = queue.builds_for_protected_runner(builds) + end # pick builds that does not have other tags than runner's one - builds = builds.matches_tag_ids(runner.tags.ids) + builds = queue.builds_matching_tag_ids(builds, runner.tags.ids) # pick builds that have at least one tag unless runner.run_untagged? - builds = builds.with_any_tags + builds = queue.builds_with_any_tags(builds) end # pick builds that older than specified age if params.key?(:job_age) - builds = builds.queued_before(params[:job_age].seconds.ago) + builds = queue.builds_queued_before(builds, params[:job_age].seconds.ago) end - build_ids = retrieve_queue(-> { builds.pluck(:id) }) + build_ids = retrieve_queue(-> { queue.execute(builds) }) @metrics.observe_queue_size(-> { build_ids.size }, @runner.runner_type) - build_ids.each do |build_id| - yield Ci::Build.find(build_id) - end + build_ids.each { |build_id| yield Ci::Build.find(build_id) } end # rubocop: enable CodeReuse/ActiveRecord @@ -204,7 +209,7 @@ module Ci # We need to use the presenter here because Gitaly calls in the presenter # may fail, and we need to ensure the response has been generated. presented_build = ::Ci::BuildRunnerPresenter.new(build) # rubocop:disable CodeReuse/Presenter - build_json = ::API::Entities::JobRequest::Response.new(presented_build).to_json + build_json = ::API::Entities::Ci::JobRequest::Response.new(presented_build).to_json Result.new(build, build_json, true) end @@ -259,63 +264,6 @@ module Ci ) end - # rubocop: disable CodeReuse/ActiveRecord - def builds_for_shared_runner - relation = new_builds. - # don't run projects which have not enabled shared runners and builds - joins(:project).where(projects: { shared_runners_enabled: true, pending_delete: false }) - .joins('LEFT JOIN project_features ON ci_builds.project_id = project_features.project_id') - .where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0') - - if Feature.enabled?(:ci_queueing_disaster_recovery, runner, type: :ops, default_enabled: :yaml) - # if disaster recovery is enabled, we fallback to FIFO scheduling - relation.order('ci_builds.id ASC') - else - # Implement fair scheduling - # this returns builds that are ordered by number of running builds - # we prefer projects that don't use shared runners at all - relation - .joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.project_id=project_builds.project_id") - .order(Arel.sql('COALESCE(project_builds.running_builds, 0) ASC'), 'ci_builds.id ASC') - end - end - - def builds_for_project_runner - new_builds.where(project: runner.projects.without_deleted.with_builds_enabled).order('id ASC') - end - - def builds_for_group_runner - # Workaround for weird Rails bug, that makes `runner.groups.to_sql` to return `runner_id = NULL` - groups = ::Group.joins(:runner_namespaces).merge(runner.runner_namespaces) - - hierarchy_groups = Gitlab::ObjectHierarchy.new(groups, options: { use_distinct: Feature.enabled?(:use_distinct_in_register_job_object_hierarchy) }).base_and_descendants - projects = Project.where(namespace_id: hierarchy_groups) - .with_group_runners_enabled - .with_builds_enabled - .without_deleted - new_builds.where(project: projects).order('id ASC') - end - - def running_builds_for_shared_runners - Ci::Build.running.where(runner: Ci::Runner.instance_type) - .group(:project_id).select(:project_id, 'count(*) AS running_builds') - end - - def all_builds - if Feature.enabled?(:ci_pending_builds_queue_join, runner, default_enabled: :yaml) - Ci::Build.joins(:queuing_entry) - else - Ci::Build.all - end - end - # rubocop: enable CodeReuse/ActiveRecord - - def new_builds - builds = all_builds.pending.unstarted - builds = builds.ref_protected if runner.ref_protected? - builds - end - def pre_assign_runner_checks { missing_dependency_failure: -> (build, _) { !build.has_valid_build_dependencies? }, -- cgit v1.2.3