Fix autocorrectable rubocop offences and implement suggestions

This commit is contained in:
Konrad Hanff
2021-04-22 08:58:50 +02:00
committed by Sebastian Serth
parent b29bc5e70f
commit 286a3f394d
7 changed files with 42 additions and 31 deletions

View File

@ -1,2 +1,4 @@
# frozen_string_literal: true
class ApplicationError < StandardError class ApplicationError < StandardError
end end

View File

@ -1,2 +1,4 @@
# frozen_string_literal: true
class RunnerNotAvailableError < ApplicationError class RunnerNotAvailableError < ApplicationError
end end

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
class ApplicationJob < ActiveJob::Base class ApplicationJob < ActiveJob::Base
queue_as :default queue_as :default
end end

View File

@ -1,13 +1,15 @@
# frozen_string_literal: true
class RunnerCleanupJob < ApplicationJob class RunnerCleanupJob < ApplicationJob
CLEANUP_INTERVAL = CodeOcean::Config.new(:code_ocean).read[:runner_management][:cleanup_interval].seconds CLEANUP_INTERVAL = CodeOcean::Config.new(:code_ocean).read[:runner_management][:cleanup_interval].seconds
after_perform do |job| after_perform do |_job|
# re-schedule job # re-schedule job
self.class.set(wait: CLEANUP_INTERVAL).perform_later self.class.set(wait: CLEANUP_INTERVAL).perform_later
end end
def perform def perform
Rails.logger.debug(Time.now) Rails.logger.debug(Time.zone.now)
Runner.inactive_runners.each do |runner| Runner.inactive_runners.each do |runner|
Rails.logger.debug("Destroying runner #{runner.runner_id}, unused since #{runner.last_used}") Rails.logger.debug("Destroying runner #{runner.runner_id}, unused since #{runner.last_used}")
runner.destroy runner.destroy

View File

@ -10,20 +10,22 @@ class Runner < ApplicationRecord
belongs_to :execution_environment belongs_to :execution_environment
belongs_to :user, polymorphic: true belongs_to :user, polymorphic: true
before_create :get_runner before_create :new_runner
before_destroy :destroy_runner before_destroy :destroy_runner
validates :execution_environment_id, presence: true validates :execution_environment, presence: true
validates :user, presence: true validates :user, presence: true
validates :time_limit, presence: true validates :time_limit, presence: true
scope :inactive_runners, -> { where('last_used < ?', Time.now - UNUSED_EXPIRATION_TIME) } scope :inactive_runners, -> { where('last_used < ?', Time.zone.now - UNUSED_EXPIRATION_TIME) }
def self.for(user, exercise, time_limit = 0) def self.for(user, exercise)
execution_environment = ExecutionEnvironment.find(exercise.execution_environment_id) execution_environment = ExecutionEnvironment.find(exercise.execution_environment_id)
runner = Runner.find_or_create_by(user: user, execution_environment: execution_environment, time_limit: time_limit) runner = Runner.find_or_create_by(user: user, execution_environment: execution_environment,
time_limit: execution_environment.permitted_execution_time)
return runner if runner.save return runner if runner.save
raise(RunnerNotAvailableError, 'No runner available') raise(RunnerNotAvailableError, 'No runner available')
end end
@ -31,22 +33,22 @@ class Runner < ApplicationRecord
url = "#{runner_url}/files" url = "#{runner_url}/files"
body = {files: files.map { |filename, content| {filepath: filename, content: content} }} body = {files: files.map { |filename, content| {filepath: filename, content: content} }}
response = Faraday.patch(url, body.to_json, HEADERS) response = Faraday.patch(url, body.to_json, HEADERS)
if response.status == 404 return unless response.status == 404
# runner has disappeared for some reason
self.destroy # runner has disappeared for some reason
raise(RunnerNotAvailableError, "Runner unavailable") destroy
end raise(RunnerNotAvailableError, 'Runner unavailable')
end end
def execute_command(command) def execute_command(command)
used_now
url = "#{runner_url}/execute" url = "#{runner_url}/execute"
response = Faraday.post(url, {command: command}.to_json, HEADERS) response = Faraday.post(url, {command: command}.to_json, HEADERS)
if response.status == 404 if response.status == 404
# runner has disappeared for some reason # runner has disappeared for some reason
self.destroy destroy
raise(RunnerNotAvailableError, "Runner unavailable") raise(RunnerNotAvailableError, 'Runner unavailable')
end end
used_now
parse response parse response
end end
@ -71,10 +73,9 @@ class Runner < ApplicationRecord
private private
def get_runner def new_runner
url = "#{BASE_URL}/runners" url = "#{BASE_URL}/runners"
body = {executionEnvironmentId: execution_environment.id} body = {executionEnvironmentId: execution_environment.id, timeLimit: time_limit}
body[:timeLimit] = time_limit
response = Faraday.post(url, body.to_json, HEADERS) response = Faraday.post(url, body.to_json, HEADERS)
response_body = parse response response_body = parse response
self.runner_id = response_body[:runnerId] self.runner_id = response_body[:runnerId]
@ -90,7 +91,7 @@ class Runner < ApplicationRecord
end end
def used_now def used_now
self.last_used = Time.now self.last_used = Time.zone.now
save save
end end
end end

View File

@ -72,7 +72,7 @@ class Submission < ApplicationRecord
# expects the full file path incl. file extension # expects the full file path incl. file extension
# Caution: There must be no unnecessary path prefix included. # Caution: There must be no unnecessary path prefix included.
# Use `file.ext` rather than `./file.ext` # Use `file.ext` rather than `./file.ext`
collect_files.detect {|file| file.filepath == file_path } collect_files.detect { |file| file.filepath == file_path }
end end
def normalized_score def normalized_score
@ -144,18 +144,18 @@ class Submission < ApplicationRecord
prepared_runner do |runner| prepared_runner do |runner|
scores = collect_files.select(&:teacher_defined_assessment?).map do |file| scores = collect_files.select(&:teacher_defined_assessment?).map do |file|
score_command = command_for execution_environment.test_command, file.name_with_extension score_command = command_for execution_environment.test_command, file.name_with_extension
stdout = "" stdout = ''
stderr = "" stderr = ''
exit_code = 1 # default to error exit_code = 1 # default to error
execution_time = runner.execute_interactively(score_command) do |runner, socket| execution_time = runner.execute_interactively(score_command) do |_runner, socket|
socket.on :stderr do |data| socket.on :stderr do |data|
stderr << data stderr << data
end end
socket.on :stdout do |data| socket.on :stdout do |data|
stdout << data stdout << data
end end
socket.on :exit do |_exit_code| socket.on :exit do |received_exit_code|
exit_code = _exit_code exit_code = received_exit_code
EventMachine.stop_event_loop EventMachine.stop_event_loop
end end
end end
@ -163,9 +163,9 @@ class Submission < ApplicationRecord
file_role: file.role, file_role: file.role,
waiting_for_container_time: runner.waiting_time, waiting_for_container_time: runner.waiting_time,
container_execution_time: execution_time, container_execution_time: execution_time,
status: (exit_code == 0) ? :ok : :failed, status: exit_code.zero? ? :ok : :failed,
stdout: stdout, stdout: stdout,
stderr: stderr, stderr: stderr
} }
test_result(output, file) test_result(output, file)
end end
@ -194,10 +194,10 @@ class Submission < ApplicationRecord
end end
def prepared_runner def prepared_runner
request_time = Time.now request_time = Time.zone.now
runner = Runner.for(user, exercise, execution_environment.permitted_execution_time) runner = Runner.for(user, exercise)
copy_files_to runner copy_files_to runner
runner.waiting_time = Time.now - request_time runner.waiting_time = Time.zone.now - request_time
yield(runner) if block_given? yield(runner) if block_given?
end end

View File

@ -1 +1,3 @@
# frozen_string_literal: true
RunnerCleanupJob.perform_now unless Rake.application.top_level_tasks.to_s.match?(/db:|assets:/) RunnerCleanupJob.perform_now unless Rake.application.top_level_tasks.to_s.match?(/db:|assets:/)