diff --git a/app/controllers/ping_controller.rb b/app/controllers/ping_controller.rb index efc52ff7..5db1b515 100644 --- a/app/controllers/ping_controller.rb +++ b/app/controllers/ping_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class PingController < ApplicationController - before_action :postgres_connected! + before_action :postgres_connected!, :runner_manager_healthy! after_action :verify_authorized, except: %i[index] def index @@ -20,4 +20,11 @@ class PingController < ApplicationController raise ActiveRecord::ConnectionNotEstablished end + + def runner_manager_healthy! + # any unhandled exception leads to a HTTP 500 response. + return if Runner.strategy_class.health == true + + raise Runner::Error::InternalServerError + end end diff --git a/lib/runner/strategy.rb b/lib/runner/strategy.rb index 50a55def..18ddc9f9 100644 --- a/lib/runner/strategy.rb +++ b/lib/runner/strategy.rb @@ -53,6 +53,10 @@ class Runner::Strategy raise NotImplementedError end + def self.health + raise NotImplementedError + end + def self.release raise NotImplementedError end diff --git a/lib/runner/strategy/docker_container_pool.rb b/lib/runner/strategy/docker_container_pool.rb index 81661d24..70851435 100644 --- a/lib/runner/strategy/docker_container_pool.rb +++ b/lib/runner/strategy/docker_container_pool.rb @@ -153,6 +153,16 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy end end + def self.health + url = "#{config[:url]}/ping" + response = Faraday.get(url) + JSON.parse(response.body)['message'] == 'Pong' + rescue Faraday::Error => e + raise Runner::Error::FaradayError.new("Request to DockerContainerPool failed: #{e.inspect}") + rescue JSON::ParserError => e + raise Runner::Error::UnexpectedResponse.new("DockerContainerPool returned invalid JSON: #{e.inspect}") + end + def self.release url = "#{config[:url]}/docker_container_pool/dump_info" response = Faraday.get(url) diff --git a/lib/runner/strategy/null.rb b/lib/runner/strategy/null.rb index c1c05879..34ee5f82 100644 --- a/lib/runner/strategy/null.rb +++ b/lib/runner/strategy/null.rb @@ -45,6 +45,10 @@ class Runner::Strategy::Null < Runner::Strategy def self.config; end + def self.health + true + end + def self.release 'N/A' end diff --git a/lib/runner/strategy/poseidon.rb b/lib/runner/strategy/poseidon.rb index 6be9b1f8..54ccf526 100644 --- a/lib/runner/strategy/poseidon.rb +++ b/lib/runner/strategy/poseidon.rb @@ -216,6 +216,22 @@ class Runner::Strategy::Poseidon < Runner::Strategy @config ||= CodeOcean::Config.new(:code_ocean).read[:runner_management] || {} end + def self.health + url = "#{config[:url]}/health" + Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Checking health from #{url}" } + response = http_connection.get url + case response.status + when 204 + true + else + raise Runner::Error::UnexpectedResponse.new("Poseidon sent unexpected response status code #{response.status}") + end + rescue Faraday::Error => e + raise Runner::Error::FaradayError.new("Request to Poseidon failed: #{e.inspect}") + ensure + Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Finished getting health information" } + end + def self.release url = "#{config[:url]}/version" Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Getting release from #{url}" }