Fix Thread leakage when scoring or testing submissions

It is discouraged to do anything directly within the
Tubesock hijack block. We might only use the callbacks
(onopen, onmessage, onclose, onerror). Otherwise,
Tubesock might not close all Threads correctly and
will keep them awake every five seconds.
This commit is contained in:
Sebastian Serth
2022-04-07 19:56:34 +02:00
parent 692cb1107e
commit 0583076c2b
3 changed files with 28 additions and 27 deletions

View File

@ -42,7 +42,7 @@ gem 'sass-rails'
gem 'slim-rails' gem 'slim-rails'
gem 'sorcery' # Causes a deprecation warning in Rails 6.0+, see: https://github.com/Sorcery/sorcery/pull/255 gem 'sorcery' # Causes a deprecation warning in Rails 6.0+, see: https://github.com/Sorcery/sorcery/pull/255
gem 'telegraf' gem 'telegraf'
gem 'tubesock', github: 'gosukiwi/tubesock', branch: 'patch-1' # Switch to a fork which is compatible with Rails 5 gem 'tubesock'
gem 'turbolinks' gem 'turbolinks'
gem 'webpacker' gem 'webpacker'
gem 'whenever', require: false gem 'whenever', require: false

View File

@ -6,15 +6,6 @@ GIT
json (~> 2.6.1) json (~> 2.6.1)
structured_warnings (~> 0.4.0) structured_warnings (~> 0.4.0)
GIT
remote: https://github.com/gosukiwi/tubesock.git
revision: 86a5ca4f7d3c3a7b9a727ad91df3b9b4912eda39
branch: patch-1
specs:
tubesock (0.2.7)
rack (>= 1.5.0)
websocket (>= 1.1.0)
GIT GIT
remote: https://github.com/openHPI/proforma.git remote: https://github.com/openHPI/proforma.git
revision: dc68000325388e1d75f31be9e136a82edad8a56d revision: dc68000325388e1d75f31be9e136a82edad8a56d
@ -162,7 +153,7 @@ GEM
regexp_parser (~> 2.2) regexp_parser (~> 2.2)
erubi (1.10.0) erubi (1.10.0)
eventmachine (1.2.7) eventmachine (1.2.7)
excon (0.92.1) excon (0.92.2)
factory_bot (6.2.1) factory_bot (6.2.1)
activesupport (>= 5.0.0) activesupport (>= 5.0.0)
factory_bot_rails (6.2.0) factory_bot_rails (6.2.0)
@ -238,7 +229,7 @@ GEM
listen (3.7.1) listen (3.7.1)
rb-fsevent (~> 0.10, >= 0.10.3) rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10) rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.15.0) loofah (2.16.0)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.7.1) mail (2.7.1)
@ -264,7 +255,7 @@ GEM
mnemosyne-ruby (1.12.1) mnemosyne-ruby (1.12.1)
activesupport (>= 4) activesupport (>= 4)
bunny bunny
msgpack (1.4.5) msgpack (1.5.1)
multi_json (1.15.0) multi_json (1.15.0)
multi_xml (0.6.0) multi_xml (0.6.0)
nested_form (0.3.2) nested_form (0.3.2)
@ -287,7 +278,7 @@ GEM
rack (>= 1.2, < 3) rack (>= 1.2, < 3)
pagedown-bootstrap-rails (2.1.4) pagedown-bootstrap-rails (2.1.4)
railties (> 3.1) railties (> 3.1)
parallel (1.22.0) parallel (1.22.1)
parser (3.1.1.0) parser (3.1.1.0)
ast (~> 2.4.1) ast (~> 2.4.1)
path_expander (1.1.0) path_expander (1.1.0)
@ -397,7 +388,7 @@ GEM
rspec-expectations (3.11.0) rspec-expectations (3.11.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0) rspec-support (~> 3.11.0)
rspec-mocks (3.11.0) rspec-mocks (3.11.1)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0) rspec-support (~> 3.11.0)
rspec-rails (5.1.1) rspec-rails (5.1.1)
@ -495,6 +486,9 @@ GEM
temple (0.8.2) temple (0.8.2)
thor (1.2.1) thor (1.2.1)
tilt (2.0.10) tilt (2.0.10)
tubesock (0.2.9)
rack (>= 1.5.0)
websocket (>= 1.1.0)
turbolinks (5.2.1) turbolinks (5.2.1)
turbolinks-source (~> 5.2) turbolinks-source (~> 5.2)
turbolinks-source (5.2.0) turbolinks-source (5.2.0)
@ -603,7 +597,7 @@ DEPENDENCIES
sorcery sorcery
spring spring
telegraf telegraf
tubesock! tubesock
turbolinks turbolinks
web-console web-console
webmock webmock

View File

@ -85,7 +85,10 @@ class SubmissionsController < ApplicationController
hijack do |tubesock| hijack do |tubesock|
client_socket = tubesock client_socket = tubesock
return kill_client_socket(client_socket) if @embed_options[:disable_run]
client_socket.onopen do |_event|
kill_client_socket(client_socket) if @embed_options[:disable_run]
end
client_socket.onclose do |_event| client_socket.onclose do |_event|
runner_socket&.close(:terminated_by_client) runner_socket&.close(:terminated_by_client)
@ -177,16 +180,18 @@ class SubmissionsController < ApplicationController
def score def score
hijack do |tubesock| hijack do |tubesock|
return if @embed_options[:disable_score] tubesock.onopen do |_event|
kill_client_socket(tubesock) if @embed_options[:disable_score]
tubesock.send_data(JSON.dump(@submission.calculate_score)) tubesock.send_data(JSON.dump(@submission.calculate_score))
# To enable hints when scoring a submission, uncomment the next line: # To enable hints when scoring a submission, uncomment the next line:
# send_hints(tubesock, StructuredError.where(submission: @submission)) # send_hints(tubesock, StructuredError.where(submission: @submission))
kill_client_socket(tubesock)
end
rescue Runner::Error => e rescue Runner::Error => e
tubesock.send_data JSON.dump({cmd: :status, status: :container_depleted}) tubesock.send_data JSON.dump({cmd: :status, status: :container_depleted})
Rails.logger.debug { "Runner error while scoring submission #{@submission.id}: #{e.message}" }
ensure
kill_client_socket(tubesock) kill_client_socket(tubesock)
Rails.logger.debug { "Runner error while scoring submission #{@submission.id}: #{e.message}" }
end end
end end
@ -196,14 +201,16 @@ class SubmissionsController < ApplicationController
def test def test
hijack do |tubesock| hijack do |tubesock|
return kill_client_socket(tubesock) if @embed_options[:disable_run] tubesock.onopen do |_event|
kill_client_socket(tubesock) if @embed_options[:disable_run]
tubesock.send_data(JSON.dump(@submission.test(@file))) tubesock.send_data(JSON.dump(@submission.test(@file)))
kill_client_socket(tubesock)
end
rescue Runner::Error => e rescue Runner::Error => e
tubesock.send_data JSON.dump({cmd: :status, status: :container_depleted}) tubesock.send_data JSON.dump({cmd: :status, status: :container_depleted})
Rails.logger.debug { "Runner error while testing submission #{@submission.id}: #{e.message}" }
ensure
kill_client_socket(tubesock) kill_client_socket(tubesock)
Rails.logger.debug { "Runner error while testing submission #{@submission.id}: #{e.message}" }
end end
end end