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); }
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); }
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)); }
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()); } }
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()); } }
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)); }