diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-20 17:22:11 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-20 17:22:11 +0300 |
commit | 0c872e02b2c822e3397515ec324051ff540f0cd5 (patch) | |
tree | ce2fb6ce7030e4dad0f4118d21ab6453e5938cdd /app/graphql/types/ci/runner_type.rb | |
parent | f7e05a6853b12f02911494c4b3fe53d9540d74fc (diff) |
Add latest changes from gitlab-org/gitlab@15-7-stable-eev15.7.0-rc42
Diffstat (limited to 'app/graphql/types/ci/runner_type.rb')
-rw-r--r-- | app/graphql/types/ci/runner_type.rb | 93 |
1 files changed, 48 insertions, 45 deletions
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb index a9c76974850..5d34906f7b8 100644 --- a/app/graphql/types/ci/runner_type.rb +++ b/app/graphql/types/ci/runner_type.rb @@ -23,6 +23,9 @@ module Types deprecated: { reason: 'Use paused', milestone: '14.8' } field :admin_url, GraphQL::Types::String, null: true, description: 'Admin URL of the runner. Only available for administrators.' + field :architecture_name, GraphQL::Types::String, null: true, + description: 'Architecture provided by the the runner.', + method: :architecture field :contacted_at, Types::TimeType, null: true, description: 'Timestamp of last contact from this runner.', method: :contacted_at @@ -35,32 +38,39 @@ module Types field :executor_name, GraphQL::Types::String, null: true, description: 'Executor last advertised by the runner.', method: :executor_name - field :platform_name, GraphQL::Types::String, null: true, - description: 'Platform provided by the runner.', - method: :platform - field :architecture_name, GraphQL::Types::String, null: true, - description: 'Architecture provided by the the runner.', - method: :architecture - field :maintenance_note, GraphQL::Types::String, null: true, - description: 'Runner\'s maintenance notes.' - field :groups, ::Types::GroupType.connection_type, null: true, - description: 'Groups the runner is associated with. For group runners only.' + field :groups, 'Types::GroupConnection', + null: true, + resolver: ::Resolvers::Ci::RunnerGroupsResolver, + description: 'Groups the runner is associated with. For group runners only.' field :id, ::Types::GlobalIDType[::Ci::Runner], null: false, description: 'ID of the runner.' field :ip_address, GraphQL::Types::String, null: true, description: 'IP address of the runner.' field :job_count, GraphQL::Types::Int, null: true, description: "Number of jobs processed by the runner (limited to #{JOB_COUNT_LIMIT}, plus one to indicate that more items exist)." + field :job_execution_status, + Types::Ci::RunnerJobExecutionStatusEnum, + null: true, + description: 'Job execution status of the runner.', + deprecated: { milestone: '15.7', reason: :alpha } field :jobs, ::Types::Ci::JobType.connection_type, null: true, description: 'Jobs assigned to the runner. This field can only be resolved for one runner in any single request.', authorize: :read_builds, resolver: ::Resolvers::Ci::RunnerJobsResolver field :locked, GraphQL::Types::Boolean, null: true, description: 'Indicates the runner is locked.' + field :maintenance_note, GraphQL::Types::String, null: true, + description: 'Runner\'s maintenance notes.' field :maximum_timeout, GraphQL::Types::Int, null: true, description: 'Maximum timeout (in seconds) for jobs processed by the runner.' + field :owner_project, ::Types::ProjectType, null: true, + description: 'Project that owns the runner. For project runners only.', + resolver: ::Resolvers::Ci::RunnerOwnerProjectResolver field :paused, GraphQL::Types::Boolean, null: false, description: 'Indicates the runner is paused and not available to run jobs.' + field :platform_name, GraphQL::Types::String, null: true, + description: 'Platform provided by the runner.', + method: :platform field :project_count, GraphQL::Types::Int, null: true, description: 'Number of projects that the runner is associated with.' field :projects, @@ -88,9 +98,6 @@ module Types method: :token_expires_at field :version, GraphQL::Types::String, null: true, description: 'Version of the runner.' - field :owner_project, ::Types::ProjectType, null: true, - description: 'Project that owns the runner. For project runners only.', - resolver: ::Resolvers::Ci::RunnerOwnerProjectResolver markdown_field :maintenance_note_html, null: true @@ -99,8 +106,25 @@ module Types end def job_count - # We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT - runner.builds.limit(JOB_COUNT_LIMIT + 1).count + BatchLoader::GraphQL.for(runner.id).batch(key: :job_count) do |runner_ids, loader, _args| + # rubocop: disable CodeReuse/ActiveRecord + # We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT + builds_tbl = ::Ci::Build.arel_table + runners_tbl = ::Ci::Runner.arel_table + lateral_query = ::Ci::Build.select(1) + .where(builds_tbl['runner_id'].eq(runners_tbl['id'])) + .limit(JOB_COUNT_LIMIT + 1) + counts = ::Ci::Runner.joins("JOIN LATERAL (#{lateral_query.to_sql}) builds_with_limit ON true") + .id_in(runner_ids) + .select(:id, Arel.star.count.as('count')) + .group(:id) + .index_by(&:id) + # rubocop: enable CodeReuse/ActiveRecord + + runner_ids.each do |runner_id| + loader.call(runner_id, counts[runner_id]&.count || 0) + end + end end def admin_url @@ -111,14 +135,13 @@ module Types Gitlab::Routing.url_helpers.edit_admin_runner_url(runner) if can_admin_runners? end - # rubocop: disable CodeReuse/ActiveRecord def project_count BatchLoader::GraphQL.for(runner.id).batch(key: :runner_project_count) do |ids, loader, args| counts = ::Ci::Runner.project_type .select(:id, 'COUNT(ci_runner_projects.id) as count') .left_outer_joins(:runner_projects) - .where(id: ids) - .group(:id) + .id_in(ids) + .group(:id) # rubocop: disable CodeReuse/ActiveRecord .index_by(&:id) ids.each do |id| @@ -126,12 +149,15 @@ module Types end end end - # rubocop: enable CodeReuse/ActiveRecord - def groups - return unless runner.group_type? + def job_execution_status + BatchLoader::GraphQL.for(runner.id).batch(key: :running_builds_exist) do |runner_ids, loader| + statuses = ::Ci::Runner.id_in(runner_ids).with_running_builds.index_by(&:id) - batched_owners(::Ci::RunnerNamespace, Group, :runner_groups, :namespace_id) + runner_ids.each do |runner_id| + loader.call(runner_id, statuses[runner_id] ? :running : :idle) + end + end end private @@ -139,29 +165,6 @@ module Types def can_admin_runners? context[:current_user]&.can_admin_all_resources? end - - # rubocop: disable CodeReuse/ActiveRecord - def batched_owners(runner_assoc_type, assoc_type, key, column_name) - BatchLoader::GraphQL.for(runner.id).batch(key: key) do |runner_ids, loader| - plucked_runner_and_owner_ids = runner_assoc_type - .select(:runner_id, column_name) - .where(runner_id: runner_ids) - .pluck(:runner_id, column_name) - # In plucked_runner_and_owner_ids, first() represents the runner ID, and second() the owner ID, - # so let's group the owner IDs by runner ID - runner_owner_ids_by_runner_id = plucked_runner_and_owner_ids - .group_by(&:first) - .transform_values { |runner_and_owner_id| runner_and_owner_id.map(&:second) } - - owner_ids = runner_owner_ids_by_runner_id.values.flatten.uniq - owners = assoc_type.where(id: owner_ids).index_by(&:id) - - runner_ids.each do |runner_id| - loader.call(runner_id, runner_owner_ids_by_runner_id[runner_id]&.map { |owner_id| owners[owner_id] } || []) - end - end - end - # rubocop: enable CodeReuse/ActiveRecord end end end |