Adapt dashboard to show idle and used runners
This commit is contained in:
@ -68,7 +68,7 @@ $(document).on('turbolinks:load', function() {
|
|||||||
_.each(response.docker, function(data) {
|
_.each(response.docker, function(data) {
|
||||||
groups.update({
|
groups.update({
|
||||||
id: data.id,
|
id: data.id,
|
||||||
visible: data.pool_size > 0
|
visible: data.prewarmingPoolSize > 0
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -78,26 +78,27 @@ $(document).on('turbolinks:load', function() {
|
|||||||
dataset.add({
|
dataset.add({
|
||||||
group: data.id,
|
group: data.id,
|
||||||
x: vis.moment(),
|
x: vis.moment(),
|
||||||
y: data.quantity
|
y: data.usedRunners
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateProgressBar = function(progress_bar, data) {
|
var updateProgressBar = function(progress_bar, data) {
|
||||||
var percentage = Math.min(Math.round(data.quantity / data.pool_size * 100), 100);
|
var percentage = Math.min(Math.round(data.idleRunners / data.prewarmingPoolSize * 100), 100);
|
||||||
progress_bar.attr({
|
progress_bar.attr({
|
||||||
'aria-valuemax': data.pool_size,
|
'aria-valuemax': data.prewarmingPoolSize,
|
||||||
'aria-valuenow': data.quantity,
|
'aria-valuenow': data.idleRunners,
|
||||||
style: 'width: ' + percentage + '%'
|
style: 'width: ' + percentage + '%'
|
||||||
});
|
});
|
||||||
progress_bar.html(data.quantity);
|
progress_bar.html(data.idleRunners);
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateTable = function(response) {
|
var updateTable = function(response) {
|
||||||
_.each(response.docker, function(data) {
|
_.each(response.docker, function(data) {
|
||||||
var row = $('tbody tr[data-id=' + data.id + ']');
|
var row = $('tbody tr[data-id=' + data.id + ']');
|
||||||
$('.pool-size', row).html(data.pool_size);
|
$('.prewarming-pool-size', row).html(data.prewarmingPoolSize);
|
||||||
var progress_bar = $('.quantity .progress .progress-bar', row);
|
$('.used-runners', row).html(`+ ${data.usedRunners}`);
|
||||||
|
var progress_bar = $('.idle-runners .progress .progress-bar', row);
|
||||||
updateProgressBar(progress_bar, data);
|
updateProgressBar(progress_bar, data);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,18 @@ module Admin
|
|||||||
end
|
end
|
||||||
|
|
||||||
ExecutionEnvironment.order(:id).select(:id, :pool_size).map do |execution_environment|
|
ExecutionEnvironment.order(:id).select(:id, :pool_size).map do |execution_environment|
|
||||||
execution_environment.attributes.merge(quantity: pool_size[execution_environment.id])
|
# Fetch the actual values (ID is stored as a symbol) or get an empty hash for merge
|
||||||
|
actual = pool_size[execution_environment.id.to_s.to_sym] || {}
|
||||||
|
|
||||||
|
template = {
|
||||||
|
id: execution_environment.id,
|
||||||
|
prewarmingPoolSize: execution_environment.pool_size,
|
||||||
|
idleRunners: 0,
|
||||||
|
usedRunners: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Existing values in the template get replaced with actual values
|
||||||
|
template.merge(actual)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -10,33 +10,38 @@ h1 = t('breadcrumbs.dashboard.show')
|
|||||||
h2 Version
|
h2 Version
|
||||||
|
|
||||||
div.mb-4
|
div.mb-4
|
||||||
= "CodeOcean Release:"
|
= application_name
|
||||||
|
=< t("admin.dashboard.show.release")
|
||||||
|
| :
|
||||||
pre = Sentry.configuration.release
|
pre = Sentry.configuration.release
|
||||||
|
|
||||||
- if Runner.management_active?
|
- if Runner.management_active?
|
||||||
div.mb-4
|
div.mb-4
|
||||||
= Runner.strategy_class.name.demodulize
|
= Runner.strategy_class.name.demodulize
|
||||||
=< "Release:"
|
=< t("admin.dashboard.show.release")
|
||||||
|
| :
|
||||||
pre = Runner.strategy_class.release
|
pre = Runner.strategy_class.release
|
||||||
|
|
||||||
h2 Docker
|
h2 Docker
|
||||||
|
|
||||||
- if Runner.management_active?
|
- if Runner.management_active?
|
||||||
h3 = t('.current')
|
h3 = t('admin.dashboard.show.current')
|
||||||
.table-responsive
|
.table-responsive
|
||||||
table.table
|
table.table
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th = t('activerecord.models.execution_environment.one')
|
th = t('activerecord.models.execution_environment.one')
|
||||||
th = t('activerecord.attributes.execution_environment.pool_size')
|
th = t('activerecord.attributes.execution_environment.pool_size')
|
||||||
th = t('.quantity')
|
th = t('admin.dashboard.show.idleRunners')
|
||||||
|
th = t('admin.dashboard.show.usedRunners')
|
||||||
tbody
|
tbody
|
||||||
- ExecutionEnvironment.order(:name).each do |execution_environment|
|
- ExecutionEnvironment.order(:name).each do |execution_environment|
|
||||||
tr data-id=execution_environment.id
|
tr data-id=execution_environment.id
|
||||||
td.name = link_to_if(policy(execution_environment).show?, execution_environment, execution_environment)
|
td.name = link_to_if(policy(execution_environment).show?, execution_environment, execution_environment)
|
||||||
td.pool-size
|
td.prewarming-pool-size
|
||||||
td.quantity = progress_bar(0)
|
td.idle-runners = progress_bar(0)
|
||||||
h3 = t('.history')
|
td.used-runners
|
||||||
|
h3 = t('admin.dashboard.show.history')
|
||||||
#graph
|
#graph
|
||||||
- else
|
- else
|
||||||
p = t('.inactive')
|
p = t('admin.dashboard.show.inactive')
|
||||||
|
@ -241,10 +241,12 @@ de:
|
|||||||
admin:
|
admin:
|
||||||
dashboard:
|
dashboard:
|
||||||
show:
|
show:
|
||||||
|
release: Release
|
||||||
current: Aktuelle Verfügbarkeit
|
current: Aktuelle Verfügbarkeit
|
||||||
history: Verfügbarkeitsverlauf
|
history: Nutzungsverlauf
|
||||||
inactive: Es ist kein Runner Management aktiv.
|
inactive: Es ist kein Runner Management aktiv.
|
||||||
quantity: Verfügbare Container
|
idleRunners: Freie Runner
|
||||||
|
usedRunners: Reservierte Runner
|
||||||
application:
|
application:
|
||||||
not_authorized: Sie Sind nicht berechtigt, diese Aktion auszuführen.
|
not_authorized: Sie Sind nicht berechtigt, diese Aktion auszuführen.
|
||||||
welcome:
|
welcome:
|
||||||
|
@ -241,10 +241,12 @@ en:
|
|||||||
admin:
|
admin:
|
||||||
dashboard:
|
dashboard:
|
||||||
show:
|
show:
|
||||||
|
release: Release
|
||||||
current: Current Availability
|
current: Current Availability
|
||||||
history: Availability History
|
history: Usage History
|
||||||
inactive: No runner management is currently enabled.
|
inactive: No runner management is currently enabled.
|
||||||
quantity: Available Containers
|
idleRunners: Idle Runners
|
||||||
|
usedRunners: Reserved Runners
|
||||||
application:
|
application:
|
||||||
not_authorized: You are not authorized to perform this action.
|
not_authorized: You are not authorized to perform this action.
|
||||||
welcome:
|
welcome:
|
||||||
|
@ -166,7 +166,7 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy
|
|||||||
url = "#{config[:url]}/docker_container_pool/quantities"
|
url = "#{config[:url]}/docker_container_pool/quantities"
|
||||||
response = Faraday.get(url)
|
response = Faraday.get(url)
|
||||||
pool_size = JSON.parse(response.body)
|
pool_size = JSON.parse(response.body)
|
||||||
pool_size.transform_keys(&:to_i)
|
pool_size.deep_symbolize_keys
|
||||||
rescue Faraday::Error => e
|
rescue Faraday::Error => e
|
||||||
raise Runner::Error::FaradayError.new("Request to DockerContainerPool failed: #{e.inspect}")
|
raise Runner::Error::FaradayError.new("Request to DockerContainerPool failed: #{e.inspect}")
|
||||||
rescue JSON::ParserError => e
|
rescue JSON::ParserError => e
|
||||||
|
@ -176,7 +176,23 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.pool_size
|
def self.pool_size
|
||||||
{}
|
url = "#{config[:url]}/statistics/execution-environments"
|
||||||
|
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Getting statistics from #{url}" }
|
||||||
|
response = http_connection.get url
|
||||||
|
case response.status
|
||||||
|
when 200
|
||||||
|
response_body = parse response
|
||||||
|
response_body
|
||||||
|
else
|
||||||
|
handle_error response
|
||||||
|
end
|
||||||
|
rescue Faraday::Error => e
|
||||||
|
raise Runner::Error::FaradayError.new("Request to Poseidon failed: #{e.inspect}")
|
||||||
|
rescue JSON::ParserError => e
|
||||||
|
# Poseidon should not send invalid json
|
||||||
|
raise Runner::Error::UnexpectedResponse.new("Error parsing response from Poseidon: #{e.message}")
|
||||||
|
ensure
|
||||||
|
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Finished getting statistics" }
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.websocket_header
|
def self.websocket_header
|
||||||
|
@ -14,7 +14,7 @@ describe Admin::DashboardHelper do
|
|||||||
FactoryBot.create(:ruby)
|
FactoryBot.create(:ruby)
|
||||||
dcp = instance_double 'docker_container_pool'
|
dcp = instance_double 'docker_container_pool'
|
||||||
allow(Runner).to receive(:strategy_class).and_return dcp
|
allow(Runner).to receive(:strategy_class).and_return dcp
|
||||||
allow(dcp).to receive(:pool_size).and_return([])
|
allow(dcp).to receive(:pool_size).and_return({})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'contains an entry for every execution environment' do
|
it 'contains an entry for every execution environment' do
|
||||||
@ -22,11 +22,15 @@ describe Admin::DashboardHelper do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'contains the pool size for every execution environment' do
|
it 'contains the pool size for every execution environment' do
|
||||||
expect(docker_data.first.symbolize_keys).to include(:pool_size)
|
expect(docker_data.first.symbolize_keys).to include(:prewarmingPoolSize)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'contains the number of available containers for every execution environment' do
|
it 'contains the number of idle runners for every execution environment' do
|
||||||
expect(docker_data.first).to include(:quantity)
|
expect(docker_data.first).to include(:idleRunners)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'contains the number of used runners for every execution environment' do
|
||||||
|
expect(docker_data.first).to include(:usedRunners)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user