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 'sorcery' # Causes a deprecation warning in Rails 6.0+, see: https://github.com/Sorcery/sorcery/pull/255
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 'webpacker'
gem 'whenever', require: false

View File

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

View File

@ -85,7 +85,10 @@ class SubmissionsController < ApplicationController
hijack do |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|
runner_socket&.close(:terminated_by_client)
@ -177,16 +180,18 @@ class SubmissionsController < ApplicationController
def score
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))
# To enable hints when scoring a submission, uncomment the next line:
# send_hints(tubesock, StructuredError.where(submission: @submission))
tubesock.send_data(JSON.dump(@submission.calculate_score))
# To enable hints when scoring a submission, uncomment the next line:
# send_hints(tubesock, StructuredError.where(submission: @submission))
kill_client_socket(tubesock)
end
rescue Runner::Error => e
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)
Rails.logger.debug { "Runner error while scoring submission #{@submission.id}: #{e.message}" }
end
end
@ -196,14 +201,16 @@ class SubmissionsController < ApplicationController
def test
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
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)
Rails.logger.debug { "Runner error while testing submission #{@submission.id}: #{e.message}" }
end
end