protected async Task <RunSolutionResult> CheckSolution(string courseId, ExerciseSlide exerciseSlide, string userCode, string userId, string userName, bool waitUntilChecked, bool saveSubmissionOnCompileErrors) { var exerciseMetricId = GetExerciseMetricId(courseId, exerciseSlide); metricSender.SendCount("exercise.try"); metricSender.SendCount($"exercise.{courseId.ToLower(CultureInfo.InvariantCulture)}.try"); metricSender.SendCount($"exercise.{exerciseMetricId}.try"); var course = courseManager.GetCourse(courseId); var exerciseBlock = exerciseSlide.Exercise; var buildResult = exerciseBlock.BuildSolution(userCode); if (buildResult.HasErrors) { metricSender.SendCount($"exercise.{exerciseMetricId}.CompilationError"); } if (buildResult.HasStyleErrors) { metricSender.SendCount($"exercise.{exerciseMetricId}.StyleViolation"); } if (!saveSubmissionOnCompileErrors) { if (buildResult.HasErrors) { return new RunSolutionResult { IsCompileError = true, ErrorMessage = buildResult.ErrorMessage, ExecutionServiceName = "uLearn" } } ; } var compilationErrorMessage = buildResult.HasErrors ? buildResult.ErrorMessage : null; var dontRunSubmission = buildResult.HasErrors; var submissionLanguage = exerciseBlock.Language.Value; var submissionSandbox = (exerciseBlock as UniversalExerciseBlock)?.DockerImageName; var submission = await userSolutionsRepo.AddUserExerciseSubmission( courseId, exerciseSlide.Id, userCode, compilationErrorMessage, null, userId, "uLearn", GenerateSubmissionName(exerciseSlide, userName), submissionLanguage, submissionSandbox, dontRunSubmission?AutomaticExerciseCheckingStatus.Done : AutomaticExerciseCheckingStatus.Waiting ); if (buildResult.HasErrors) { return new RunSolutionResult { IsCompileError = true, ErrorMessage = buildResult.ErrorMessage, SubmissionId = submission.Id, ExecutionServiceName = "uLearn" } } ; var hasAutomaticChecking = exerciseBlock.HasAutomaticChecking(); var executionTimeout = TimeSpan.FromSeconds(exerciseBlock.TimeLimit * 2 + 5); try { if (hasAutomaticChecking) { await userSolutionsRepo.RunAutomaticChecking(submission, executionTimeout, waitUntilChecked); } } catch (SubmissionCheckingTimeout) { log.Error($"Не смог запустить проверку решения, никто не взял его на проверку за {executionTimeout.TotalSeconds} секунд.\nКурс «{course.Title}», слайд «{exerciseSlide.Title}» ({exerciseSlide.Id})"); errorsBot.PostToChannel($"Не смог запустить проверку решения, никто не взял его на проверку за {executionTimeout.TotalSeconds} секунд.\nКурс «{course.Title}», слайд «{exerciseSlide.Title}» ({exerciseSlide.Id})\n\nhttps://ulearn.me/Sandbox"); return(new RunSolutionResult { IsCompillerFailure = true, ErrorMessage = "К сожалению, из-за большой нагрузки мы не смогли оперативно проверить ваше решение. " + "Мы попробуем проверить его позже, просто подождите и обновите страницу. ", ExecutionServiceName = "ulearn" }); } if (!waitUntilChecked) { metricSender.SendCount($"exercise.{exerciseMetricId}.dont_wait_result"); return(new RunSolutionResult { SubmissionId = submission.Id }); } /* Update the submission */ submission = userSolutionsRepo.FindNoTrackingSubmission(submission.Id); if (submission.AutomaticCheckingIsRightAnswer) { await CreateStyleErrorsReviewsForSubmission(submission, buildResult.StyleErrors, exerciseMetricId); } var automaticChecking = submission.AutomaticChecking; bool sentToReview; if (!hasAutomaticChecking) { sentToReview = await SendToReviewAndUpdateScore(submission, courseManager, slideCheckingsRepo, groupsRepo, visitsRepo, metricSender, true).ConfigureAwait(false); } else { sentToReview = slideCheckingsRepo.HasManualExerciseChecking(courseId, exerciseSlide.Id, userId, submission.Id); } var result = new RunSolutionResult { IsCompileError = automaticChecking?.IsCompilationError ?? false, ErrorMessage = automaticChecking?.CompilationError.Text ?? "", IsRightAnswer = submission.AutomaticCheckingIsRightAnswer, ExpectedOutput = exerciseBlock.HideExpectedOutputOnError ? null : exerciseSlide.Exercise.ExpectedOutput?.NormalizeEoln(), ActualOutput = automaticChecking?.Output.Text ?? "", ExecutionServiceName = automaticChecking?.ExecutionServiceName ?? "ulearn", SentToReview = sentToReview, SubmissionId = submission.Id, }; if (buildResult.HasStyleErrors) { result.IsStyleViolation = true; result.StyleMessage = string.Join("\n", buildResult.StyleErrors.Select(e => e.GetMessageWithPositions())); } return(result); }