public async Task GetTrack(string trackId) { var track = await _context.Tracks.FirstOrDefaultAsync(t => t.Id == long.Parse(trackId)); await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); //设置初试状态 if (track.Status != JudgeStatus.Pending) { await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); await Clients.Caller.SendAsync("finish"); return; } //找题目 var problem = await _context.Problems.FirstOrDefaultAsync(q => q.Id == track.ProblemId); if (problem != null) { // 将测试数据加载到内存 var testdata = new List <TestData>(); var problemDirectory = Path.Combine(Directory.GetCurrentDirectory(), "JudgeDataStorage", problem.Id.ToString(), "data"); Directory.GetDirectories(problemDirectory).ToList().ForEach(async element => { var currentPath = Path.Combine(problemDirectory, element); TestData data = new TestData { Input = await File.ReadAllTextAsync(Path.Combine(currentPath, "data.in")), Output = await File.ReadAllTextAsync(Path.Combine(currentPath, "data.out")) }; testdata.Add(data); }); // 编译源代码 string sourceFilePath = _evaluationMachine.CreateSourceFile(track.CodeEncoded, track); string programPath = _evaluationMachine.CompileProgram(track, out Track trackOut); track = trackOut; // 将编译日志推送到客户端 await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); // 如果编译失败,可执行文件将不存在 if (!File.Exists(programPath)) { track.Status = JudgeStatus.CompileError; var pointStatus = track.GetPointStatus(); for (int i = 0; i < pointStatus.Count; i++) { pointStatus[i].Status = PointStatus.InternalError; } track.SetPointStatus(pointStatus); _context.Tracks.Update(track); await _context.SaveChangesAsync(); await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); await Clients.Caller.SendAsync("finish"); return; } var status = track.GetPointStatus(); status.ForEach(element => { element.Status = PointStatus.Judging; }); track.SetPointStatus(status); await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); var tasks = new List <Task <PointStatus> >(); for (int i = 0; i < testdata.Count; i++) { var task = new Task <PointStatus>(() => { var section = i - 1; var data = testdata[section]; var result = _evaluationMachine.RunTest(data, programPath, track, problem); return(result); }); task.Start(); tasks.Add(task); } var result = await Task.WhenAll(tasks); for (int i = 0; i < result.Length; i++) { status[i].Status = result[i]; } track.SetPointStatus(status); if (track.GetPointStatus().FirstOrDefault(x => x.Status != PointStatus.Accepted) != null) { track.Status = JudgeStatus.WrongAnswer; } else { track.Status = JudgeStatus.Accept; var passRate = problem.GetPassRate(); passRate.Pass += 1; problem.SetPassRate(passRate); _context.Update(problem); //通过题目之后要给用户加标签 var user = await _context.UserProfileModels.FirstOrDefaultAsync(q => q.Id == long.Parse(track.SubmitterId)); user.TotalAccepted++; _context.UserProfileModels.Update(user); foreach (var ProblemLabelitem in _context.ProblemLabels.Where(x => x.ProblemId == problem.Id.ToString()).ToList()) { var userLabel = await _context.UserLabels.FirstOrDefaultAsync(x => x.LabelId == ProblemLabelitem.LabelId); if (userLabel == null) { UserLabel userlabel = new UserLabel { UserId = user.Id.ToString(), LabelId = ProblemLabelitem.LabelId, Weight = 1 }; _context.UserLabels.Add(userlabel); } else { userLabel.Weight++; _context.UserLabels.Update(userLabel); } } } _context.Tracks.Update(track); await _context.SaveChangesAsync(); await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); } await Clients.Caller.SendAsync("finish"); }
public async Task GetTrack(string trackId) { var track = await _context.Tracks.FirstOrDefaultAsync(t => t.Id == long.Parse(trackId)); await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); if (track.Status != JudgeStatus.Pending) { await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); await Clients.Caller.SendAsync("finish"); return; } var problem = await _context.Problems.FirstOrDefaultAsync(q => q.Id == track.ProblemId); if (problem != null) { _logger.Log(LogLevel.Information, $"[{DateTime.UtcNow}] Starting to check code of track {track.Id}", track.CodeEncoded); // Load test data to memory var testdata = new List <TestData>(); var problemDirectory = Path.Combine(Directory.GetCurrentDirectory(), "JudgeDataStorage", problem.Id.ToString(), "data"); Directory.GetDirectories(problemDirectory).ToList().ForEach(async element => { var currentPath = Path.Combine(problemDirectory, element); TestData data = new TestData { Input = await File.ReadAllTextAsync(Path.Combine(currentPath, "data.in")), Output = await File.ReadAllTextAsync(Path.Combine(currentPath, "data.out")) }; testdata.Add(data); }); // Compile source code string sourceFilePath = _evaluationMachine.CreateSourceFile(track.CodeEncoded, track); string programPath = _evaluationMachine.CompileProgram(track, out Track trackOut); track = trackOut; // Push compile log to client await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); // If compile failed, the executable file will not be exist if (!File.Exists(programPath)) { track.Status = JudgeStatus.CompileError; var pointStatus = track.GetPointStatus(); for (int i = 0; i < pointStatus.Count; i++) { pointStatus[i].Status = PointStatus.InternalError; } track.SetPointStatus(pointStatus); _context.Tracks.Update(track); await _context.SaveChangesAsync(); await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); await Clients.Caller.SendAsync("finish"); return; } var status = track.GetPointStatus(); status.ForEach(element => { element.Status = PointStatus.Judging; }); track.SetPointStatus(status); await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); var tasks = new List <Task <PointStatus> >(); for (int i = 0; i < testdata.Count; i++) { var task = new Task <PointStatus>(() => { var section = i - 1; var data = testdata[section]; var result = _evaluationMachine.RunTest(data, programPath, track, problem); return(result); // var currentStatus = status; // currentStatus[section].Id = section; // currentStatus[section].Status = result; // status = currentStatus; // Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))).RunSynchronously(); }); task.Start(); tasks.Add(task); } var result = await Task.WhenAll(tasks); for (int i = 0; i < result.Length; i++) { status[i].Status = result[i]; } track.SetPointStatus(status); if (track.GetPointStatus().FirstOrDefault(x => x.Status != PointStatus.Accepted) != null) { track.Status = JudgeStatus.WrongAnswer; } else { track.Status = JudgeStatus.Accept; var passRate = problem.GetPassRate(); passRate.Pass += 1; problem.SetPassRate(passRate); _context.Update(problem); } _context.Tracks.Update(track); await _context.SaveChangesAsync(); await Clients.Caller.SendAsync("updateStatus", Base64Encode(JsonSerializer.Serialize(track))); _logger.Log(LogLevel.Information, $"[{DateTime.UtcNow}] Completed the check of code of track {track.Id}", track); } await Clients.Caller.SendAsync("finish"); }