public async Task <IActionResult> UpdateJudging( [FromRoute] string hostname, [FromRoute] int judgingId, [FromForm] UpdateJudgingModel model) { var host = await Judgehosts.FindAsync(hostname); // Unknown or inactive judgehost requested if (host is null) { return(Empty()); } await Judgehosts.NotifyPollAsync(host); var(judging, pid, cid, uid, time) = await Judgings.FindAsync(judgingId); if (judging is null) { return(BadRequest()); } judging.CompileError = model.output_compile ?? ""; if (model.compile_success != 1) { judging.Status = Verdict.CompileError; judging.StopTime = DateTimeOffset.Now; await FinishJudging(judging, cid, pid, uid, time); } else { await Judgings.UpdateAsync(judging); } return(Ok()); }
/// <summary> /// Finish the judging pipe, persist into database, /// create the events and notify scoreboard. /// </summary> private async Task FinishJudging(Judging j, int?cid, int pid, int uid, DateTimeOffset subtime) { if (cid == 0) { cid = null; } await Judgings.UpdateAsync(j); await HttpContext.AuditAsync( AuditlogType.Judging, cid, j.Server, "judged", $"{j.JudgingId}", $"{j.Status}"); if (cid.HasValue && j.Active) { await HttpContext.RequestServices .GetRequiredService <MediatR.IMediator>() .JudgingFinished(cid.Value, subtime, pid, uid, j); } if (j.Active) { await HttpContext.RequestServices .GetRequiredService <ISubmissionStore>() .UpdateStatisticsAsync(cid ?? 0, uid, pid, j.Status == Verdict.Accepted); } Telemetry.TrackDependency( dependencyTypeName: "JudgeHost", dependencyName: j.Server, data: $"j{j.JudgingId} judged " + j.Status, startTime: j.StartTime ?? DateTimeOffset.Now, duration: (j.StopTime - j.StartTime) ?? TimeSpan.Zero, success: j.Status != Verdict.UndefinedError); }
/// <summary> /// The judging meet an internal error, require a rejudging. /// </summary> private async Task ReturnToQueue(Judging j, int?cid, int pid, int uid, DateTimeOffset subtime) { await Judgings.CreateAsync(new Judging { Active = j.Active, Status = Verdict.Pending, FullTest = j.FullTest, RejudgeId = j.RejudgeId, PreviousJudgingId = j.PreviousJudgingId, SubmissionId = j.SubmissionId, }); j.Active = false; j.Status = Verdict.UndefinedError; j.RejudgeId = null; j.PreviousJudgingId = null; if (!j.StopTime.HasValue) { j.StopTime = DateTimeOffset.Now; } if (cid == 0) { cid = null; } await FinishJudging(j, cid, pid, uid, subtime); }
public async Task <ActionResult <List <UnfinishedJudging> > > OnPost( [FromForm, Required] string hostname) { var item = await Judgehosts.FindAsync(hostname); if (item is null) { item = await Judgehosts.CreateAsync(new JudgeHost { ServerName = hostname, PollTime = DateTimeOffset.Now, Active = true }); await HttpContext.AuditAsync( "registered", hostname, $"on {HttpContext.Connection.RemoteIpAddress}"); Telemetry.TrackDependency( dependencyTypeName: "JudgeHost", dependencyName: item.ServerName, data: "registed", startTime: item.PollTime, duration: TimeSpan.Zero, success: true); return(new List <UnfinishedJudging>()); } else { await Judgehosts.NotifyPollAsync(item); var oldJudgings = await Judgings.ListAsync( predicate : j => j.Server == item.ServerName && j.Status == Verdict.Running, selector : j => new { j, j.s.ContestId, j.s.Author, j.s.ProblemId, j.s.Time }, topCount : 10000); foreach (var sg in oldJudgings) { await ReturnToQueue(sg.j, sg.ContestId, sg.ProblemId, sg.Author, sg.Time); } return(oldJudgings .Select(s => new UnfinishedJudging { judgingid = s.j.JudgingId, submitid = s.j.SubmissionId, cid = s.ContestId }) .ToList()); } }
public async Task <ActionResult <int> > InternalError( [FromForm] InternalErrorModel model, [FromServices] IInternalErrorStore store, [FromServices] ILanguageStore langs, [FromServices] IProblemStore probs) { if (!ModelState.IsValid) { return(BadRequest()); } var toDisable = model.disabled.AsJson <InternalErrorDisable>(); var kind = toDisable.kind; var ie = await store.CreateAsync( new InternalError { JudgehostLog = model.judgehostlog, JudgingId = model.judgingid, ContestId = model.cid, Description = model.description, Disabled = model.disabled, Status = InternalErrorStatus.Open, Time = DateTimeOffset.Now, }); if (kind == "language") { var langid = toDisable.langid; await langs.ToggleJudgeAsync(langid, false); Telemetry.TrackDependency( dependencyTypeName: "Language", dependencyName: langid, data: model.description, startTime: DateTimeOffset.Now, duration: TimeSpan.Zero, success: false); } else if (kind == "judgehost") { var hostname = toDisable.hostname; await Judgehosts.ToggleAsync(hostname, false); Telemetry.TrackDependency( dependencyTypeName: "JudgeHost", dependencyName: hostname, data: model.description, startTime: DateTimeOffset.Now, duration: TimeSpan.Zero, success: false); } else if (kind == "problem") { var probid = toDisable.probid.Value; await probs.ToggleJudgeAsync(probid, false); Telemetry.TrackDependency( dependencyTypeName: "Problem", dependencyName: $"p{probid}", data: model.description, startTime: DateTimeOffset.Now, duration: TimeSpan.Zero, success: false); } else { Telemetry.TrackDependency( dependencyTypeName: "Unresolved", dependencyName: kind, data: model.description, startTime: DateTimeOffset.Now, duration: TimeSpan.Zero, success: false); } if (model.judgingid.HasValue) { var(j, pid, cid, uid, time) = await Judgings.FindAsync(model.judgingid.Value); await ReturnToQueue(j, cid, pid, uid, time); } await HttpContext.AuditAsync("added", $"{ie.ErrorId}", $"for {kind}"); return(ie.ErrorId); }
public async Task <IActionResult> AddJudgingRun( [FromRoute] string hostname, [FromRoute] int judgingId, [FromForm, ModelBinder(typeof(JudgingRunBinder))] List <JudgingRunModel> batch) { if (batch is null) { return(BadRequest()); } var host = await Judgehosts.FindAsync(hostname); if (host is null) { return(BadRequest()); // Unknown or inactive judgehost requested } await Judgehosts.NotifyPollAsync(host); var(judging, pid, cid, uid, time) = await Judgings.FindAsync(judgingId); if (judging is null) { Logger.LogError("Unknown judging result."); return(BadRequest()); } foreach (var run in batch) { var detail = await Judgings.CreateAsync(run.ParseInfo(judgingId, host.PollTime)); if (run.output_error is null || run.output_run is null) { continue; } try { var stderr = Convert.FromBase64String(run.output_error); var stdout = Convert.FromBase64String(run.output_run); await Judgings.SetRunFileAsync(judgingId, detail.TestId, "out", stdout); await Judgings.SetRunFileAsync(judgingId, detail.TestId, "err", stderr); } catch (Exception ex) { Logger.LogError(ex, "An error occurred when saving OutputError and OutputRun for j{judgingId}", judgingId); } } // Check for the final status var countTc = await HttpContext.RequestServices .GetRequiredService <ITestcaseStore>() .CountAsync(pid); var verdict = await Judgings.SummarizeAsync(judging); // testId for score, testcaseId for count of tested cases bool anyRejected = !judging.FullTest && verdict.Status != Verdict.Accepted; bool fullTested = verdict.TestcaseId >= countTc && countTc > 0; if (anyRejected || fullTested) { judging.ExecuteMemory = verdict.ExecuteMemory; judging.ExecuteTime = verdict.ExecuteTime; judging.Status = verdict.Status; judging.StopTime = host.PollTime; judging.TotalScore = verdict.TestId; await FinishJudging(judging, cid, pid, uid, time); } return(Ok()); }
public async Task <ActionResult <NextJudging> > NextJudging([FromRoute] string hostname) { var host = await Judgehosts.FindAsync(hostname); if (host is null) { return(Empty()); // Unknown or inactive judgehost requested } await Judgehosts.NotifyPollAsync(host); if (!host.Active) { return(Empty()); } var r = new { judging = (Judging)null, lang = (Language)null, prob = (Problem)null, cid = 0, teamid = 0, rjid = new int?(), }; using (await Lock.LockAsync()) { r = await Judgings.FindAsync( predicate : j => j.Status == Verdict.Pending && j.s.l.AllowJudge && j.s.p.AllowJudge && !j.s.Ignored, selector : j => new { judging = j, lang = j.s.l, prob = j.s.p, cid = j.s.ContestId, teamid = j.s.Author, rjid = j.s.RejudgeId }); if (r is null) { return(Empty()); } var judging = r.judging; judging.Status = Verdict.Running; judging.Server = host.ServerName; judging.StartTime = DateTimeOffset.Now; await Judgings.UpdateAsync(judging); //if (cid != 0) //{ // var cts = new Data.Api.ContestJudgement( // judging, next.StartTime ?? DateTimeOffset.Now); // DbContext.Events.Add(cts.ToEvent("create", cid)); //} } var toFindMd5 = new[] { r.prob.RunScript, r.prob.CompareScript, r.lang.CompileScript }; var md5s = await HttpContext.RequestServices .GetRequiredService <IExecutableStore>() .ListMd5Async(toFindMd5); var tcss = await HttpContext.RequestServices .GetRequiredService <ITestcaseStore>() .ListAsync(r.prob.ProblemId); return(new NextJudging { submitid = r.judging.SubmissionId, cid = r.cid, teamid = r.teamid, probid = r.prob.ProblemId, langid = r.lang.Id, rejudgingid = r.rjid, entry_point = null, origsubmitid = null, maxruntime = r.prob.TimeLimit * r.lang.TimeFactor / 1000.0, // as seconds memlimit = r.prob.MemoryLimit + (r.lang.Id == "java" ? 131072 : 0), // as kb, java more 128M outputlimit = r.prob.OutputLimit, // KB run = r.prob.RunScript, compare = r.prob.CompareScript, compare_args = r.prob.ComapreArguments, compile_script = r.lang.CompileScript, combined_run_compare = r.prob.CombinedRunCompare, compare_md5sum = md5s[r.prob.CompareScript], run_md5sum = md5s[r.prob.RunScript], compile_script_md5sum = md5s[r.lang.CompileScript], judgingid = r.judging.JudgingId, full_judge = r.judging.FullTest && (r.cid == 0 || r.judging.RejudgeId != null), testcases = tcss.ToDictionary(t => $"{t.Rank}", t => new TestcaseToJudge(t)) }); }