Show a localized message if the program was killed.
* This will most likely happen by the OOM killer, thus we inform the user about the memory restriction.
This commit is contained in:
@ -743,6 +743,13 @@ var CodeOceanEditor = {
|
||||
});
|
||||
},
|
||||
|
||||
showOutOfMemoryMessage: function () {
|
||||
$.flash.info({
|
||||
icon: ['fa', 'fa-clock-o'],
|
||||
text: $('#editor').data('message-out-of-memory')
|
||||
});
|
||||
},
|
||||
|
||||
showTimeoutMessage: function () {
|
||||
$.flash.info({
|
||||
icon: ['fa', 'fa-clock-o'],
|
||||
|
@ -102,6 +102,11 @@ CodeOceanEditorEvaluation = {
|
||||
})) {
|
||||
this.showTimeoutMessage();
|
||||
}
|
||||
if (_.some(response, function (result) {
|
||||
return result.status === 'out_of_memory';
|
||||
})) {
|
||||
this.showOutOfMemoryMessage();
|
||||
}
|
||||
if (_.some(response, function (result) {
|
||||
return result.status === 'container_depleted';
|
||||
})) {
|
||||
|
@ -47,6 +47,7 @@ CodeOceanEditorWebsocket = {
|
||||
this.websocket.on('render', this.renderWebsocketOutput.bind(this));
|
||||
this.websocket.on('exit', this.handleExitCommand.bind(this));
|
||||
this.websocket.on('timeout', this.showTimeoutMessage.bind(this));
|
||||
this.websocket.on('out_of_memory', this.showOutOfMemoryMessage.bind(this));
|
||||
this.websocket.on('status', this.showStatus.bind(this));
|
||||
this.websocket.on('hint', this.showHint.bind(this));
|
||||
},
|
||||
|
@ -29,10 +29,14 @@ $(document).on('turbolinks:load', function () {
|
||||
};
|
||||
|
||||
const handleResponse = function (response) {
|
||||
// Always print stdout and stderr
|
||||
printOutput(response);
|
||||
|
||||
// If an error occurred, print it too
|
||||
if (response.status === 'timeout') {
|
||||
printTimeout(response);
|
||||
} else {
|
||||
printOutput(response);
|
||||
} else if (response.status === 'out_of_memory') {
|
||||
printOutOfMemory(response);
|
||||
}
|
||||
};
|
||||
|
||||
@ -71,12 +75,19 @@ $(document).on('turbolinks:load', function () {
|
||||
};
|
||||
|
||||
const printTimeout = function (output) {
|
||||
const element = $.append('<p>');
|
||||
const element = $('<p>');
|
||||
element.addClass('text-danger');
|
||||
element.text($('#shell').data('message-timeout'));
|
||||
$('#output').append(element);
|
||||
};
|
||||
|
||||
const printOutOfMemory = function (output) {
|
||||
const element = $('<p>');
|
||||
element.addClass('text-danger');
|
||||
element.text($('#shell').data('message-out-of-memory'));
|
||||
$('#output').append(element);
|
||||
};
|
||||
|
||||
if ($('#shell').isPresent()) {
|
||||
const command = $('#command')
|
||||
command.focus();
|
||||
|
@ -157,6 +157,7 @@ class SubmissionsController < ApplicationController
|
||||
"\n#{t('exercises.implement.exit_failure', timestamp: l(Time.zone.now, format: :short), exit_code: exit_code)}"
|
||||
end
|
||||
client_socket.send_data JSON.dump({cmd: :write, stream: :stdout, data: "#{exit_statement}\n"})
|
||||
client_socket.send_data JSON.dump({cmd: :out_of_memory}) if exit_code == 137
|
||||
|
||||
close_client_connection(client_socket)
|
||||
end
|
||||
|
@ -78,13 +78,14 @@ class Runner < ApplicationRecord
|
||||
stdout = +''
|
||||
stderr = +''
|
||||
try = 0
|
||||
|
||||
exit_code = 1 # default to error
|
||||
begin
|
||||
if try.nonzero?
|
||||
request_new_id
|
||||
save
|
||||
end
|
||||
|
||||
exit_code = 1 # default to error
|
||||
execution_time = attach_to_execution(command) do |socket|
|
||||
socket.on :stderr do |data|
|
||||
stderr << data
|
||||
@ -120,7 +121,9 @@ class Runner < ApplicationRecord
|
||||
# We forward the exception if requested
|
||||
raise e if raise_exception && defined?(e) && e.present?
|
||||
|
||||
output.merge!(stdout: stdout, stderr: stderr)
|
||||
# If the process was killed with SIGKILL, it is most likely that the OOM killer was triggered.
|
||||
output[:status] = :out_of_memory if exit_code == 137
|
||||
output.merge!(stdout: stdout, stderr: stderr, exit_code: exit_code)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
h1 = @execution_environment
|
||||
|
||||
#shell data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @execution_environment.permitted_execution_time) data-url=execute_command_execution_environment_path(@execution_environment)
|
||||
#shell data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @execution_environment.permitted_execution_time) data-message-out-of-memory=t('exercises.editor.out_of_memory', memory_limit: @execution_environment.memory_limit) data-url=execute_command_execution_environment_path(@execution_environment)
|
||||
.form-group
|
||||
label for='command' = t('.command')
|
||||
input#command.form-control type='text'
|
||||
|
@ -5,7 +5,7 @@
|
||||
- show_rfc_interventions = @show_rfc_interventions || "false"
|
||||
- show_tips_interventions = @show_tips_interventions || "false"
|
||||
- hide_rfc_button = @hide_rfc_button || false
|
||||
#editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-submissions-url=submissions_path data-user-id=@current_user.id data-user-external-id=external_user_external_id data-working-times-url=working_times_exercise_path(@exercise) data-intervention-save-url=intervention_exercise_path(@exercise) data-rfc-interventions=show_rfc_interventions data-break-interventions=show_break_interventions data-tips-interventions=show_tips_interventions data-course_token=@course_token data-search-save-url=search_exercise_path(@exercise)
|
||||
#editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-message-out-of-memory=t('exercises.editor.out_of_memory', memory_limit: @exercise.execution_environment.memory_limit) data-submissions-url=submissions_path data-user-id=@current_user.id data-user-external-id=external_user_external_id data-working-times-url=working_times_exercise_path(@exercise) data-intervention-save-url=intervention_exercise_path(@exercise) data-rfc-interventions=show_rfc_interventions data-break-interventions=show_break_interventions data-tips-interventions=show_tips_interventions data-course_token=@course_token data-search-save-url=search_exercise_path(@exercise)
|
||||
- unless @embed_options[:hide_sidebar]
|
||||
|
||||
- additional_classes = 'sidebar-col'
|
||||
|
@ -360,6 +360,7 @@ de:
|
||||
submit_after_late_deadline: Code verspätet zur Bewertung abgeben
|
||||
test: Testen
|
||||
timeout: 'Ausführung gestoppt. Ihr Code hat die erlaubte Ausführungszeit von %{permitted_execution_time} Sekunden überschritten.'
|
||||
out_of_memory: 'Ausführung gestoppt. Ihr Code hat den erlaubten Arbeitsspeicher von %{memory_limit} MB überschritten.'
|
||||
exercise_deadline_passed: 'Das Ergebnis kann nicht übertragen werden.'
|
||||
tooltips:
|
||||
save: Ihr Code wird automatisch gespeichert, wann immer Sie eine Datei herunterladen, ausführen oder testen. Explizites Speichern ist also selten notwendig.
|
||||
|
@ -360,6 +360,7 @@ en:
|
||||
submit_after_late_deadline: Submit Code for Assessment After Deadline Passed
|
||||
test: Test
|
||||
timeout: 'Execution stopped. Your code exceeded the permitted execution time of %{permitted_execution_time} seconds.'
|
||||
out_of_memory: 'Execution stopped. Your code exceeded the permitted RAM usage of %{memory_limit} MB.'
|
||||
exercise_deadline_passed: 'The score cannot be submitted.'
|
||||
tooltips:
|
||||
save: Your code is automatically saved whenever you download, run, or test it. Therefore, explicitly saving is rarely necessary.
|
||||
|
Reference in New Issue
Block a user