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 () {
|
showTimeoutMessage: function () {
|
||||||
$.flash.info({
|
$.flash.info({
|
||||||
icon: ['fa', 'fa-clock-o'],
|
icon: ['fa', 'fa-clock-o'],
|
||||||
|
@ -102,6 +102,11 @@ CodeOceanEditorEvaluation = {
|
|||||||
})) {
|
})) {
|
||||||
this.showTimeoutMessage();
|
this.showTimeoutMessage();
|
||||||
}
|
}
|
||||||
|
if (_.some(response, function (result) {
|
||||||
|
return result.status === 'out_of_memory';
|
||||||
|
})) {
|
||||||
|
this.showOutOfMemoryMessage();
|
||||||
|
}
|
||||||
if (_.some(response, function (result) {
|
if (_.some(response, function (result) {
|
||||||
return result.status === 'container_depleted';
|
return result.status === 'container_depleted';
|
||||||
})) {
|
})) {
|
||||||
|
@ -47,6 +47,7 @@ CodeOceanEditorWebsocket = {
|
|||||||
this.websocket.on('render', this.renderWebsocketOutput.bind(this));
|
this.websocket.on('render', this.renderWebsocketOutput.bind(this));
|
||||||
this.websocket.on('exit', this.handleExitCommand.bind(this));
|
this.websocket.on('exit', this.handleExitCommand.bind(this));
|
||||||
this.websocket.on('timeout', this.showTimeoutMessage.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('status', this.showStatus.bind(this));
|
||||||
this.websocket.on('hint', this.showHint.bind(this));
|
this.websocket.on('hint', this.showHint.bind(this));
|
||||||
},
|
},
|
||||||
|
@ -29,10 +29,14 @@ $(document).on('turbolinks:load', function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleResponse = function (response) {
|
const handleResponse = function (response) {
|
||||||
|
// Always print stdout and stderr
|
||||||
|
printOutput(response);
|
||||||
|
|
||||||
|
// If an error occurred, print it too
|
||||||
if (response.status === 'timeout') {
|
if (response.status === 'timeout') {
|
||||||
printTimeout(response);
|
printTimeout(response);
|
||||||
} else {
|
} else if (response.status === 'out_of_memory') {
|
||||||
printOutput(response);
|
printOutOfMemory(response);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,12 +75,19 @@ $(document).on('turbolinks:load', function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const printTimeout = function (output) {
|
const printTimeout = function (output) {
|
||||||
const element = $.append('<p>');
|
const element = $('<p>');
|
||||||
element.addClass('text-danger');
|
element.addClass('text-danger');
|
||||||
element.text($('#shell').data('message-timeout'));
|
element.text($('#shell').data('message-timeout'));
|
||||||
$('#output').append(element);
|
$('#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()) {
|
if ($('#shell').isPresent()) {
|
||||||
const command = $('#command')
|
const command = $('#command')
|
||||||
command.focus();
|
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)}"
|
"\n#{t('exercises.implement.exit_failure', timestamp: l(Time.zone.now, format: :short), exit_code: exit_code)}"
|
||||||
end
|
end
|
||||||
client_socket.send_data JSON.dump({cmd: :write, stream: :stdout, data: "#{exit_statement}\n"})
|
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)
|
close_client_connection(client_socket)
|
||||||
end
|
end
|
||||||
|
@ -78,13 +78,14 @@ class Runner < ApplicationRecord
|
|||||||
stdout = +''
|
stdout = +''
|
||||||
stderr = +''
|
stderr = +''
|
||||||
try = 0
|
try = 0
|
||||||
|
|
||||||
|
exit_code = 1 # default to error
|
||||||
begin
|
begin
|
||||||
if try.nonzero?
|
if try.nonzero?
|
||||||
request_new_id
|
request_new_id
|
||||||
save
|
save
|
||||||
end
|
end
|
||||||
|
|
||||||
exit_code = 1 # default to error
|
|
||||||
execution_time = attach_to_execution(command) do |socket|
|
execution_time = attach_to_execution(command) do |socket|
|
||||||
socket.on :stderr do |data|
|
socket.on :stderr do |data|
|
||||||
stderr << data
|
stderr << data
|
||||||
@ -120,7 +121,9 @@ class Runner < ApplicationRecord
|
|||||||
# We forward the exception if requested
|
# We forward the exception if requested
|
||||||
raise e if raise_exception && defined?(e) && e.present?
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
h1 = @execution_environment
|
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
|
.form-group
|
||||||
label for='command' = t('.command')
|
label for='command' = t('.command')
|
||||||
input#command.form-control type='text'
|
input#command.form-control type='text'
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
- show_rfc_interventions = @show_rfc_interventions || "false"
|
- show_rfc_interventions = @show_rfc_interventions || "false"
|
||||||
- show_tips_interventions = @show_tips_interventions || "false"
|
- show_tips_interventions = @show_tips_interventions || "false"
|
||||||
- hide_rfc_button = @hide_rfc_button || 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]
|
- unless @embed_options[:hide_sidebar]
|
||||||
|
|
||||||
- additional_classes = 'sidebar-col'
|
- additional_classes = 'sidebar-col'
|
||||||
|
@ -360,6 +360,7 @@ de:
|
|||||||
submit_after_late_deadline: Code verspätet zur Bewertung abgeben
|
submit_after_late_deadline: Code verspätet zur Bewertung abgeben
|
||||||
test: Testen
|
test: Testen
|
||||||
timeout: 'Ausführung gestoppt. Ihr Code hat die erlaubte Ausführungszeit von %{permitted_execution_time} Sekunden überschritten.'
|
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.'
|
exercise_deadline_passed: 'Das Ergebnis kann nicht übertragen werden.'
|
||||||
tooltips:
|
tooltips:
|
||||||
save: Ihr Code wird automatisch gespeichert, wann immer Sie eine Datei herunterladen, ausführen oder testen. Explizites Speichern ist also selten notwendig.
|
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
|
submit_after_late_deadline: Submit Code for Assessment After Deadline Passed
|
||||||
test: Test
|
test: Test
|
||||||
timeout: 'Execution stopped. Your code exceeded the permitted execution time of %{permitted_execution_time} seconds.'
|
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.'
|
exercise_deadline_passed: 'The score cannot be submitted.'
|
||||||
tooltips:
|
tooltips:
|
||||||
save: Your code is automatically saved whenever you download, run, or test it. Therefore, explicitly saving is rarely necessary.
|
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