Attach duration information to the exception object
This commit is contained in:

committed by
Sebastian Serth

parent
36578a2817
commit
2dff81a510
@ -193,15 +193,23 @@ class SubmissionsController < ApplicationController
|
||||
kill_socket(tubesock)
|
||||
Rails.logger.debug { "Running a submission timed out: #{e.message}" }
|
||||
@output = "timeout: #{@output}"
|
||||
extract_durations(e)
|
||||
rescue Runner::Error => e
|
||||
tubesock.send_data JSON.dump({cmd: :status, status: :container_depleted})
|
||||
kill_socket(tubesock)
|
||||
Rails.logger.debug { "Runner error while running a submission: #{e.message}" }
|
||||
extract_durations(e)
|
||||
ensure
|
||||
save_run_output
|
||||
end
|
||||
end
|
||||
|
||||
def extract_durations(error)
|
||||
@container_execution_time = error.execution_duration
|
||||
@waiting_for_container_time = error.waiting_duration
|
||||
end
|
||||
private :extract_durations
|
||||
|
||||
def kill_socket(tubesock)
|
||||
# search for errors and save them as StructuredError (for scoring runs see submission.rb)
|
||||
errors = extract_errors
|
||||
@ -293,6 +301,7 @@ class SubmissionsController < ApplicationController
|
||||
def statistics; end
|
||||
|
||||
# TODO: make this run, but with the test command
|
||||
# TODO: add this method to the before action for set_submission again
|
||||
# def test
|
||||
# hijack do |tubesock|
|
||||
# unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive?
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
class Runner
|
||||
class Error < ApplicationError
|
||||
attr_accessor :waiting_duration, :execution_duration
|
||||
|
||||
class BadRequest < Error; end
|
||||
|
||||
class EnvironmentNotFound < Error; end
|
||||
|
@ -41,7 +41,14 @@ class Runner < ApplicationRecord
|
||||
end
|
||||
|
||||
def attach_to_execution(command, &block)
|
||||
@strategy.attach_to_execution(command, &block)
|
||||
starting_time = Time.zone.now
|
||||
begin
|
||||
@strategy.attach_to_execution(command, &block)
|
||||
rescue Runner::Error => e
|
||||
e.execution_duration = Time.zone.now - starting_time
|
||||
raise
|
||||
end
|
||||
Time.zone.now - starting_time # execution duration
|
||||
end
|
||||
|
||||
def destroy_at_management
|
||||
|
@ -140,6 +140,7 @@ class Submission < ApplicationRecord
|
||||
|
||||
def calculate_score
|
||||
file_scores = nil
|
||||
# If prepared_runner raises an error, no Testrun will be created.
|
||||
prepared_runner do |runner, waiting_duration|
|
||||
file_scores = collect_files.select(&:teacher_defined_assessment?).map do |file|
|
||||
score_command = command_for execution_environment.test_command, file.name_with_extension
|
||||
@ -163,10 +164,10 @@ class Submission < ApplicationRecord
|
||||
output.merge!(container_execution_time: execution_time, status: exit_code.zero? ? :ok : :failed)
|
||||
rescue Runner::Error::ExecutionTimeout => e
|
||||
Rails.logger.debug("Running tests in #{file.name_with_extension} for submission #{id} timed out: #{e.message}")
|
||||
output.merge!(status: :timeout)
|
||||
output.merge!(status: :timeout, container_execution_time: e.execution_duration)
|
||||
rescue Runner::Error => e
|
||||
Rails.logger.debug("Running tests in #{file.name_with_extension} for submission #{id} failed: #{e.message}")
|
||||
output.merge!(status: :failed)
|
||||
output.merge!(status: :failed, container_execution_time: e.execution_duration)
|
||||
ensure
|
||||
output.merge!(stdout: stdout, stderr: stderr)
|
||||
end
|
||||
@ -182,6 +183,9 @@ class Submission < ApplicationRecord
|
||||
prepared_runner do |runner, waiting_duration|
|
||||
durations[:execution_duration] = runner.attach_to_execution(run_command, &block)
|
||||
durations[:waiting_duration] = waiting_duration
|
||||
rescue Runner::Error => e
|
||||
e.waiting_duration = waiting_duration
|
||||
raise
|
||||
end
|
||||
durations
|
||||
end
|
||||
@ -190,8 +194,13 @@ class Submission < ApplicationRecord
|
||||
|
||||
def prepared_runner
|
||||
request_time = Time.zone.now
|
||||
runner = Runner.for(user, exercise)
|
||||
runner.copy_files(collect_files)
|
||||
begin
|
||||
runner = Runner.for(user, exercise)
|
||||
runner.copy_files(collect_files)
|
||||
rescue Runner::Error => e
|
||||
e.waiting_duration = Time.zone.now - request_time
|
||||
raise
|
||||
end
|
||||
waiting_duration = Time.zone.now - request_time
|
||||
yield(runner, waiting_duration)
|
||||
end
|
||||
|
Reference in New Issue
Block a user