Esempio n. 1
0
        public async Task <bool> Update(ClientJudgeModel model)
        {
            SolutionLock solutionLock = await _db.SolutionLocks.FindAsync(model.SolutionId);

            // 未被锁住,或者锁住的客户端不正确,或者锁已经过期,则不允许操作。
            if (solutionLock == null)
            {
                return(false);
            }
            if (solutionLock.LockClientId != Guid.Parse(Context.ConnectionId) || solutionLock.LockEndTime < DateTime.Now)
            {
                _db.Entry(solutionLock).State = EntityState.Deleted;
                await _db.SaveChangesAsync();

                return(false);
            }

            // 锁住,允许操作,然后改变状态。
            Solution solution = await _db.Solutions
                                .Include(x => x.WrongAnswer)
                                .FirstOrDefaultAsync(x => x.Id == model.SolutionId);

            model.UpdateSolution(solution);

            // 删除锁,保存数据。
            _db.Entry(solution).State     = EntityState.Modified;
            _db.Entry(solutionLock).State = EntityState.Deleted;
            await _db.SaveChangesAsync();

            SolutionHub.PushChange(solution.Id, solution.State, model.RunTimeMs, model.UsingMemoryMb);

            return(true);
        }
Esempio n. 2
0
        public async Task <bool> Update(ClientJudgeModel model)
        {
            var result = await _server.Invoke <bool>(AppSettings.HubUpdate, model);

            if (_log.IsDebugEnabled)
            {
                _log.DebugExt(() => JsonConvert.SerializeObject(result));
            }
            else
            {
                _log.InfoExt(() => $"Commit {model.SolutionId}-{model.StateId}, {model.RunTimeMs}ms,{model.UsingMemoryMb}MB");
            }
            return(result);
        }
Esempio n. 3
0
        private async Task Judge(CompileResult res1, CompileResult res2, Encoding languageEncoding)
        {
            int   peakRunTimeMs = 0;
            float peakMemoryMb  = 0;

            var info = new Process2JudgeInfo
            {
                MemoryLimitMb = _fullM.MemoryLimitMb,
                TimeLimitMs   = _fullM.TimeLimitMs,
                Path1         = res1.PathToAssembly,
                Path2         = res2.PathToAssembly
            };

            for (short times = 0; times < _fullM.RunTimes; ++times)
            {
                _log.DebugExt($"NativeDll Juding {times + 1} of {_fullM.RunTimes}...");
                Process2JudgeResult result = Sandbox.Process2Judge(info, languageEncoding);
                _log.DebugExt("NativeDll Judged.");

                peakRunTimeMs = Math.Max(peakRunTimeMs, result.TimeMs);
                peakMemoryMb  = Math.Max(peakMemoryMb, result.MemoryMb);

                if (!result.Process1Ok)
                {
                    await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.RuntimeError, peakRunTimeMs, peakMemoryMb));

                    return;
                }
                if (!result.Process2Ok)
                {
                    await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.RuntimeError, peakRunTimeMs, peakMemoryMb));

                    return;
                }

                if (!result.Accepted)
                {
                    await _client.Update(ClientJudgeModel.CreateProcess2WrongAnswer(_spush.Id, peakRunTimeMs, peakMemoryMb, result.P1Result.Output, result.P2Result.Output));

                    return;
                }
            }

            await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.Accepted, peakRunTimeMs, peakMemoryMb));
        }
Esempio n. 4
0
        public override async Task ExecuteAsync()
        {
            // 获取并锁定解答的详情。
            _sfull = await _client.Lock(_spush.Id);

            if (_sfull == null)
            {
                _log.InfoExt(() => $"Failed to lock {_spush.Id}, move next.");
                return;
            }
            await UpdateQuestionData();

            var           compiler = CompilerProvider.GetCompiler(_spush.Language);
            CompileResult asm      = compiler.Compile(_sfull.Source);

            if (asm.HasErrors)
            {
                await _client.Update(ClientJudgeModel.CreateCompileError(_spush.Id, asm.Output));

                return;
            }
            else
            {
                await _client.UpdateInLock(_spush.Id, SolutionState.Judging);
            }

            IEnumerable <QuestionData> datas;

            using (var db = new JudgerDbContext())
            {
                var dataIds = _sfull.QuestionDatas
                              .Select(x => x.Id).ToArray();
                datas = await db.FindDatasByIds(dataIds);
            }

            // Judging
            using (compiler)
            {
                await Judge(datas, asm, compiler.GetEncoding());
            }
        }
Esempio n. 5
0
        public override async Task ExecuteAsync()
        {
            _lockM = await _client.LockProcess2(_spush.Id);

            if (_lockM == null)
            {
                _log.InfoExt($"Failed to lock {_spush.Id}, move next.");
                return;
            }
            await UpdateQuestionProcess2Code();

            // _fullM 里面包含 评测进程 的源代码,因此它是 compiler1;
            // _lockM 里面包含 待评测进程 的源代码,因此它是 compiler2。
            using (var judgerCompiler = CompilerProvider.GetCompiler(_fullM.Language))
                using (var judgedCompiler = CompilerProvider.GetCompiler(_spush.Language))
                {
                    CompileResult res1 = judgerCompiler.Compile(_fullM.Code);
                    if (res1.HasErrors)
                    {
                        await _client.Update(ClientJudgeModel.CreateCompileError(_spush.Id, res1.Output)); // 评测代码 编译失败,属系统错误

                        return;
                    }

                    CompileResult res2 = judgedCompiler.Compile(_lockM.Source);
                    if (res2.HasErrors)
                    {
                        await _client.Update(ClientJudgeModel.CreateCompileError(_spush.Id, res2.Output)); // 待评测代码 编译失败,属用户错误

                        return;
                    }

                    await _client.UpdateInLock(_spush.Id, SolutionState.Judging);

                    await Judge(res1, res2, judgedCompiler.GetEncoding());
                }
        }
Esempio n. 6
0
        private async Task Judge(IEnumerable <QuestionData> datas, CompileResult asm, Encoding languageEncoding)
        {
            int   runTimeMs    = 0;
            float peakMemoryMb = 0;

            foreach (QuestionData data in datas)
            {
                if (_spush.Language == Languages.Java)
                {
                    data.MemoryLimitMb += AppSettings.JavaGivenMemoryMb;
                }
                var info = new JudgeInfo
                {
                    Input         = data.Input,
                    MemoryLimitMb = data.MemoryLimitMb,
                    Path          = asm.PathToAssembly,
                    TimeLimitMs   = data.TimeLimit,
                };

                _log.DebugExt("NativeDll Juding...");
                var result = Sandbox.Judge(info, languageEncoding);
                _log.DebugExt("NativeDll Judged...");

                runTimeMs   += result.TimeMs;
                peakMemoryMb = Math.Max(peakMemoryMb, result.MemoryMb);

                if (!result.IsDone)
                {
                    await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.RuntimeError, runTimeMs, peakMemoryMb)); // system error

                    return;
                }
                if (result.TimeMs >= data.TimeLimit)
                {
                    await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.TimeLimitExceed, runTimeMs, peakMemoryMb));

                    return;
                }
                if (result.MemoryMb >= data.MemoryLimitMb)
                {
                    await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.MemoryLimitExceed, runTimeMs, peakMemoryMb));

                    return;
                }
                if (result.ExitCode != 0)
                {
                    await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.RuntimeError, runTimeMs, peakMemoryMb)); // application error

                    return;
                }

                var trimed = result.Output.TrimEnd();
                if (trimed != data.Output)
                {
                    _log.DebugExt(() => $"\r\nExpected: \r\n{data.Output} \r\nActual: \r\n{result.Output}");
                    await _client.Update(ClientJudgeModel.CreateWrongAnswer(_spush.Id, runTimeMs, peakMemoryMb, data.Id, trimed));

                    return;
                }
            }
            await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.Accepted, runTimeMs, peakMemoryMb));
        }