/// <summary>
        /// 将给定的 SubmissionLanguage 枚举值转换为对应的字符串。
        /// </summary>
        /// <param name="value">要转换的 SubmissionLanguage 枚举值。</param>
        /// <returns>转换后的字符串。</returns>
        /// <exception cref="ArgumentException"/>
        public static string ConvertToString(SubmissionLanguage value)
        {
            switch (value)
            {
            case SubmissionLanguage.GnuC:
                return(GnuCString);

            case SubmissionLanguage.GnuCPlusPlus:
                return(GnuCPlusPlusString);

            case SubmissionLanguage.GnuCPlusPlus11:
                return(GnuCPlusPlus11String);

            case SubmissionLanguage.GnuCPlusPlus14:
                return(GnuCPlusPlus14String);

            case SubmissionLanguage.GnuCPlusPlus17:
                return(GnuCPlusPlus17String);

            case SubmissionLanguage.MicrosoftCPlusPlus:
                return(MicrosoftCPlusPlusString);

            case SubmissionLanguage.Java:
                return(JavaString);

            case SubmissionLanguage.Pascal:
                return(PascalString);

            case SubmissionLanguage.Python2:
                return(Python2String);

            case SubmissionLanguage.Python3:
                return(Python3String);

            default:
                throw new ArgumentException("给定的 SubmissionLanguage 枚举值无效。");
            }
        }
        public async Task <UserExerciseSubmission> AddUserExerciseSubmission(
            string courseId, Guid slideId,
            string code, string compilationError, string output,
            string userId, string executionServiceName, string displayName,
            SubmissionLanguage language,
            AutomaticExerciseCheckingStatus status = AutomaticExerciseCheckingStatus.Waiting)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                code = "// no code";
            }
            var hash = (await textsRepo.AddText(code)).Hash;
            var compilationErrorHash = (await textsRepo.AddText(compilationError)).Hash;
            var outputHash           = (await textsRepo.AddText(output)).Hash;

            AutomaticExerciseChecking automaticChecking;

            if (language.HasAutomaticChecking())
            {
                automaticChecking = new AutomaticExerciseChecking
                {
                    CourseId             = courseId,
                    SlideId              = slideId,
                    UserId               = userId,
                    Timestamp            = DateTime.Now,
                    CompilationErrorHash = compilationErrorHash,
                    IsCompilationError   = !string.IsNullOrWhiteSpace(compilationError),
                    OutputHash           = outputHash,
                    ExecutionServiceName = executionServiceName,
                    DisplayName          = displayName,
                    Status               = status,
                    IsRightAnswer        = false,
                };

                db.AutomaticExerciseCheckings.Add(automaticChecking);
            }
            else
            {
                automaticChecking = null;
            }

            var submission = new UserExerciseSubmission
            {
                CourseId          = courseId,
                SlideId           = slideId,
                UserId            = userId,
                Timestamp         = DateTime.Now,
                SolutionCodeHash  = hash,
                CodeHash          = code.Split('\n').Select(x => x.Trim()).Aggregate("", (x, y) => x + y).GetHashCode(),
                Likes             = new List <Like>(),
                AutomaticChecking = automaticChecking,
                AutomaticCheckingIsRightAnswer = automaticChecking?.IsRightAnswer ?? true,
                Language = language,
            };

            db.UserExerciseSubmissions.Add(submission);

            await db.SaveChangesAsync();

            return(submission);
        }
        private async Task <UserExerciseSubmission> TryGetExerciseSubmission(string agentName, SubmissionLanguage language)
        {
            var notSoLongAgo = DateTime.Now - TimeSpan.FromMinutes(15);
            UserExerciseSubmission submission;

            using (var transaction = db.Database.BeginTransaction(IsolationLevel.Serializable))
            {
                var submissionsQueryable = db.UserExerciseSubmissions
                                           .AsNoTracking()
                                           .Where(s =>
                                                  s.Timestamp > notSoLongAgo &&
                                                  s.AutomaticChecking.Status == AutomaticExerciseCheckingStatus.Waiting &&
                                                  s.Language == language);

                if (!submissionsQueryable.Any())
                {
                    return(null);
                }

                var maxId = submissionsQueryable.Select(s => s.Id).DefaultIfEmpty(-1).Max();
                submission = submissionsQueryable.FirstOrDefault(s => s.Id == maxId);
                if (submission == null)
                {
                    return(null);
                }

                /* Mark submission as "running" */
                submission.AutomaticChecking.Status            = AutomaticExerciseCheckingStatus.Running;
                submission.AutomaticChecking.CheckingAgentName = agentName;

                await SaveAll(new List <AutomaticExerciseChecking> {
                    submission.AutomaticChecking
                });

                transaction.Commit();

                db.ObjectContext().AcceptAllChanges();
            }

            unhandledSubmissions.TryRemove(submission.Id, out _);

            return(submission);
        }
        public async Task <UserExerciseSubmission> GetUnhandledSubmission(string agentName, SubmissionLanguage language)
        {
            log.Info("GetUnhandledSubmission(): trying to acquire semaphore");
            var semaphoreLocked = await getSubmissionSemaphore.WaitAsync(TimeSpan.FromSeconds(2));

            if (!semaphoreLocked)
            {
                log.Error("GetUnhandledSubmission(): Can't lock semaphore for 2 seconds");
                return(null);
            }
            log.Info("GetUnhandledSubmission(): semaphore acquired!");

            try
            {
                return(await TryGetExerciseSubmission(agentName, language));
            }
            catch (Exception e)
            {
                log.Error("GetUnhandledSubmission() error", e);
                return(null);
            }
            finally
            {
                log.Info("GetUnhandledSubmission(): trying to release semaphore");
                getSubmissionSemaphore.Release();
                log.Info("GetUnhandledSubmission(): semaphore released");
            }
        }
 public static bool HasAutomaticChecking(this SubmissionLanguage language)
 {
     /* For a while only C# has automatic checking on ulearn */
     return(language == SubmissionLanguage.CSharp);
 }
Exemple #6
0
        private async Task <List <UserExerciseSubmission> > TryGetExerciseSubmissions(int count, string agentName, SubmissionLanguage language)
        {
            var notSoLongAgo = DateTime.Now - TimeSpan.FromMinutes(15);
            List <UserExerciseSubmission> submissions;

            using (var transaction = db.Database.BeginTransaction(IsolationLevel.Serializable))
            {
                submissions = db.UserExerciseSubmissions
                              .AsNoTracking()
                              .Where(s =>
                                     s.Timestamp > notSoLongAgo &&
                                     s.AutomaticChecking.Status == AutomaticExerciseCheckingStatus.Waiting &&
                                     s.Language == language)
                              .OrderByDescending(s => s.Timestamp)
                              .Take(count)
                              .ToList();
                foreach (var submission in submissions)
                {
                    submission.AutomaticChecking.Status            = AutomaticExerciseCheckingStatus.Running;
                    submission.AutomaticChecking.CheckingAgentName = agentName;
                }

                await SaveAll(submissions.Select(s => s.AutomaticChecking));

                transaction.Commit();

                db.ObjectContext().AcceptAllChanges();
            }

            foreach (var submission in submissions)
            {
                unhandledSubmissions.TryRemove(submission.Id, out _);
            }

            return(submissions);
        }