Add `jobExecutionStatus` to CiRunnerManager in GraphQL API
Description
In order for the runner manager list to provide information on the current job status IDLE
or RUNNING
, we should add this field to the runner manager.
Example:
query getRunnerManagers($runnerId: CiRunnerID!) {
runner(id: $runnerId) {
id
managers {
count
nodes {
id
systemId
jobExecutionStatus # new field
}
}
}
}
Implementation plan
Introduce a job_execution_status
field in CiRunnerManagerType
leveraging a new Ci::RunnerManager.with_running_builds
scope, as follows:
diff --git a/app/graphql/types/ci/runner_manager_type.rb b/app/graphql/types/ci/runner_manager_type.rb
index b36c8f428628..f847a4fb1c22 100644
--- a/app/graphql/types/ci/runner_manager_type.rb
+++ b/app/graphql/types/ci/runner_manager_type.rb
@@ -26,6 +26,11 @@ class RunnerManagerType < BaseObject
description: 'ID of the runner manager.'
field :ip_address, GraphQL::Types::String, null: true,
description: 'IP address of the runner manager.'
+ field :job_execution_status,
+ Types::Ci::RunnerJobExecutionStatusEnum,
+ null: true,
+ description: 'Job execution status of the runner manager.',
+ alpha: { milestone: '16.4' }
field :platform_name, GraphQL::Types::String, null: true,
description: 'Platform provided by the runner manager.',
method: :platform
@@ -44,6 +49,18 @@ class RunnerManagerType < BaseObject
def executor_name
::Ci::Runner::EXECUTOR_TYPE_TO_NAMES[runner_manager.executor_type&.to_sym]
end
+
+ private
+
+ def job_execution_status
+ BatchLoader::GraphQL.for(runner_manager.id).batch(key: :running_builds_exist) do |runner_manager_ids, loader|
+ statuses = ::Ci::RunnerManager.id_in(runner_manager_ids).with_running_builds.index_by(&:id)
+
+ runner_manager_ids.each do |runner_manager_id|
+ loader.call(runner_manager_id, statuses[runner_manager_id] ? :running : :idle)
+ end
+ end
+ end
end
end
end
diff --git a/app/models/ci/runner_manager.rb b/app/models/ci/runner_manager.rb
index 3a3f95a8c699..d659056c26d4 100644
--- a/app/models/ci/runner_manager.rb
+++ b/app/models/ci/runner_manager.rb
@@ -48,6 +48,15 @@ class RunnerManager < Ci::ApplicationRecord
where(runner_id: runner_id)
end
+ scope :with_running_builds, -> do
+ where('EXISTS(?)',
+ joins(:builds)
+ .joins(:runner_manager_builds)
+ .select(1)
+ .where(ci_builds: { status: :running })
+ )
+ end
+
def self.online_contact_time_deadline
Ci::Runner.online_contact_time_deadline
end