From 575057acd3dcc323d0023adfd2609c00fe3b723f Mon Sep 17 00:00:00 2001 From: Konrad Hanff Date: Wed, 7 Apr 2021 14:43:34 +0200 Subject: [PATCH] Fix some non-autocorrectable linting issues Many functions in submission_controller.rb still are very long and have a high complexity. Because the logic for handling execution of submissions will probably move elsewhere (when switching to ActionCable), this is fine for now. --- app/controllers/submissions_controller.rb | 63 +++++++++-------------- lib/runner/runner.rb | 3 +- lib/runner/runner_connection.rb | 37 ++++++++----- 3 files changed, 48 insertions(+), 55 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 27d7a5d6..9f5b7a9d 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -10,7 +10,6 @@ class SubmissionsController < ApplicationController before_action :set_submission, only: %i[download download_file render_file run score extract_errors show statistics test] - # before_action :set_docker_client, only: %i[run test] before_action :set_files, only: %i[download download_file render_file show run] before_action :set_file, only: %i[download_file render_file run] before_action :set_mime_type, only: %i[download_file render_file] @@ -135,7 +134,7 @@ class SubmissionsController < ApplicationController def handle_websockets(tubesock, container, socket) tubesock.send_data JSON.dump({'cmd' => 'status', 'status' => :container_running}) - @output = '' + @output = String.new socket.on :output do |data| Rails.logger.info("#{Time.zone.now.getutc}: Container sending: #{data}") @@ -176,40 +175,27 @@ class SubmissionsController < ApplicationController else Rails.logger.info("Unknown command from client: #{event[:cmd]}") end - rescue JSON::ParserError => e - ails.logger.debug { "Data received from client is not valid json: #{data}" } + rescue JSON::ParserError + Rails.logger.debug { "Data received from client is not valid json: #{data}" } Sentry.set_extras(data: data) - rescue TypeError => e + rescue TypeError Rails.logger.debug { "JSON data received from client cannot be parsed to hash: #{data}" } Sentry.set_extras(data: data) end end def run - # TODO: do we need this thread? If so, how to fix double render? (to reproduce: remove .join and run) - Thread.new do - hijack do |tubesock| - if @embed_options[:disable_run] - kill_socket(tubesock) - else - @container_execution_time = @submission.run(sanitize_filename) do |container, socket| - @waiting_for_container_time = container.waiting_time - handle_websockets(tubesock, container, socket) - end - save_run_output + hijack do |tubesock| + if @embed_options[:disable_run] + kill_socket(tubesock) + else + @container_execution_time = @submission.run(sanitize_filename) do |container, socket| + @waiting_for_container_time = container.waiting_time + handle_websockets(tubesock, container, socket) end + save_run_output end - ensure - ActiveRecord::Base.connection_pool.release_connection - end.join - # TODO: determine if this is necessary - # unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive? - # Thread.new do - # EventMachine.run - # ensure - # ActiveRecord::Base.connection_pool.release_connection - # end - # end + end end def kill_socket(tubesock) @@ -306,21 +292,20 @@ class SubmissionsController < ApplicationController def statistics; end - # TODO: is this needed? + # TODO: make this run, but with the test command # def test - # Thread.new do - # hijack do |tubesock| - # if @embed_options[:disable_run] - # kill_socket(tubesock) - # return - # end - # @container_request_time = Time.now - # @submission.run_tests(sanitize_filename) do |container| - # handle_websockets(tubesock, container) + # hijack do |tubesock| + # unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive? + # Thread.new do + # EventMachine.run + # ensure + # ActiveRecord::Base.connection_pool.release_connection # end # end - # ensure - # ActiveRecord::Base.connection_pool.release_connection + # output = @docker_client.execute_test_command(@submission, sanitize_filename) + # # tubesock is the socket to the client + # tubesock.send_data JSON.dump(output) + # tubesock.send_data JSON.dump('cmd' => 'exit') # end # end diff --git a/lib/runner/runner.rb b/lib/runner/runner.rb index dbaa8a5c..5e850e9e 100644 --- a/lib/runner/runner.rb +++ b/lib/runner/runner.rb @@ -50,8 +50,7 @@ class Runner end def status - # parse(Faraday.get(runner_url))[:status].to_sym - # TODO return actual state retrieved via websocket + # TODO: return actual state retrieved via websocket :timeouted end diff --git a/lib/runner/runner_connection.rb b/lib/runner/runner_connection.rb index ae654dd1..4f692edd 100644 --- a/lib/runner/runner_connection.rb +++ b/lib/runner/runner_connection.rb @@ -43,20 +43,7 @@ class RunnerConnection return unless BACKEND_OUTPUT_SCHEMA.valid?(JSON.parse(event.data)) event = decode(event.data) - - # TODO: handle other events like timeout - case event[:type].to_sym - when :exit_code - @exit_code = event[:data] - when :stderr - @stderr_callback.call event[:data] - @output_callback.call event[:data] - when :stdout - @stdout_callback.call event[:data] - @output_callback.call event[:data] - else - :error - end + __send__("handle_#{event[:type]}", event) end def on_open(_event) @@ -68,4 +55,26 @@ class RunnerConnection def on_close(_event) @exit_callback.call @exit_code end + + def handle_exit(event) + @exit_code = event[:data] + end + + def handle_stdout(event) + @stdout_callback.call event[:data] + @output_callback.call event[:data] + end + + def handle_stderr(event) + @stderr_callback.call event[:data] + @output_callback.call event[:data] + end + + def handle_error(event) end + + def handle_start(event) end + + def handle_timeout(event) + # TODO: set the runner state + end end