From e8a21ea319eecd831073f9d0b76b032b2490b2e2 Mon Sep 17 00:00:00 2001 From: Sebastian Serth Date: Tue, 21 Mar 2023 07:34:31 +0100 Subject: [PATCH] Further optimize extracting errors The previous solution worked, but always queried all ErrorTemplateAttributes, even if there was no match of the ErrorTemplate. This solution resolves this issue and still benefits from less SQL queries. --- app/controllers/submissions_controller.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 2f2bd9dc..f8e51328 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -353,9 +353,17 @@ class SubmissionsController < ApplicationController def extract_errors results = [] if @testrun[:output].present? - @submission.exercise.execution_environment.error_templates.left_joins(:error_template_attributes).includes(:error_template_attributes).each do |template| + # First, we test all error templates for a match. + matching_error_templates = @submission.exercise.execution_environment.error_templates.select do |template| pattern = Regexp.new(template.signature).freeze - results << StructuredError.create_from_template(template, @testrun[:output], @submission) if pattern.match(@testrun[:output]) + pattern.match(@testrun[:output]) + end + # Second, if there is a match, we preload all ErrorTemplateAttributes and create a StructuredError + # + # Reloading the ErrorTemplate is necessary to allow preloading the ErrorTemplateAttributes. + # However, this results in less (and faster) SQL queries than performing manual lookups. + ErrorTemplate.where(id: matching_error_templates).joins(:error_template_attributes).includes(:error_template_attributes).each do |template| + results << StructuredError.create_from_template(template, @testrun[:output], @submission) end end results