Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql/types/ci/runner_type.rb')
-rw-r--r--app/graphql/types/ci/runner_type.rb93
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