123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- package com.example.onlinejudge.judge;
- import cn.hutool.json.JSONUtil;
- import com.example.onlinejudge.exception.BusinessException;
- import com.example.onlinejudge.judge.codesandbox.CodeSandbox;
- import com.example.onlinejudge.judge.codesandbox.CodeSandboxFactory;
- import com.example.onlinejudge.judge.codesandbox.CodeSandboxProxy;
- import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeRequest;
- import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeResponse;
- import com.example.onlinejudge.judge.codesandbox.model.JudgeInfo;
- import com.example.onlinejudge.judge.strategy.JudgeContext;
- import com.example.onlinejudge.model.dto.question.JudgeCase;
- import com.example.onlinejudge.model.entity.Question;
- import com.example.onlinejudge.model.entity.QuestionSubmit;
- import com.example.onlinejudge.common.result.ResultCode;
- import com.example.onlinejudge.model.enums.QuestionSubmitStatusEnum;
- import com.example.onlinejudge.service.QuestionService;
- import com.example.onlinejudge.service.QuestionSubmitService;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- import javax.annotation.Resource;
- import java.util.List;
- import java.util.stream.Collectors;
- @Service
- public class JudgeServiceImpl implements JudgeService{
- @Resource
- private QuestionService questionService;
- @Resource
- private QuestionSubmitService questionSubmitService;
- @Resource
- private JudgeManager judgeManager;
- @Value("${codesandbox.type:example}")
- private String type;
- @Override
- public QuestionSubmit doJudge(long questionSubmitId) {
- System.out.println("判题服务开始");
- System.out.println("questionSubmitId: " + questionSubmitId);
- // 1)传入题目的提交 id,获取到对应的题目、提交信息(包含代码、编程语言等)
- QuestionSubmit questionSubmit = questionSubmitService.getById(questionSubmitId);
- if (questionSubmit == null) {
- System.out.println("提交信息不存在");
- throw new BusinessException(ResultCode.NOT_FOUND_ERROR, "提交信息不存在");
- }
- Long questionId = questionSubmit.getQuestionId();
- Question question = questionService.getById(questionId);
- if (question == null) {
- System.out.println("题目不存在");
- throw new BusinessException(ResultCode.NOT_FOUND_ERROR, "题目不存在");
- }
- System.out.println("1结束");
- // 2)如果题目提交状态不为等待中,就不用重复执行了
- if (!questionSubmit.getStatus().equals(QuestionSubmitStatusEnum.WAITING.getValue())) {
- throw new BusinessException(ResultCode.OPERATION_ERROR, "题目正在判题中");
- }
- System.out.println("2结束");
- // 3)更改判题(题目提交)的状态为 “判题中”,防止重复执行
- QuestionSubmit questionSubmitUpdate = new QuestionSubmit();
- questionSubmitUpdate.setId(questionSubmitId);
- questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.RUNNING.getValue());
- boolean update = questionSubmitService.updateById(questionSubmitUpdate);
- if (!update) {
- throw new BusinessException(ResultCode.SYSTEM_ERROR, "题目状态更新错误");
- }
- System.out.println("准备开始判题");
- // 4)调用沙箱,获取到执行结果
- CodeSandbox codeSandbox = CodeSandboxFactory.newInstance(type);
- System.out.println(codeSandbox);
- codeSandbox = new CodeSandboxProxy(codeSandbox);
- String language = questionSubmit.getLanguage();
- String code = questionSubmit.getCode();
- // 获取输入用例
- String judgeCaseStr = question.getJudgeCase();
- List<JudgeCase> judgeCaseList = JSONUtil.toList(judgeCaseStr, JudgeCase.class);
- List<String> inputList = judgeCaseList.stream().map(JudgeCase::getInput).collect(Collectors.toList());
- ExecuteCodeRequest executeCodeRequest = ExecuteCodeRequest.builder()
- .code(code)
- .language(language)
- .inputList(inputList)
- .build();
- ExecuteCodeResponse executeCodeResponse = codeSandbox.executeCode(executeCodeRequest);
- List<String> outputList = executeCodeResponse.getOutputList();
- // 5)根据沙箱的执行结果,设置题目的判题状态和信息
- JudgeContext judgeContext = new JudgeContext();
- judgeContext.setJudgeInfo(executeCodeResponse.getJudgeInfo());
- judgeContext.setInputList(inputList);
- judgeContext.setOutputList(outputList);
- judgeContext.setJudgeCaseList(judgeCaseList);
- judgeContext.setQuestion(question);
- judgeContext.setQuestionSubmit(questionSubmit);
- JudgeInfo judgeInfo = judgeManager.doJudge(judgeContext);
- // 6)修改数据库中的判题结果
- questionSubmitUpdate = new QuestionSubmit();
- questionSubmitUpdate.setId(questionSubmitId);
- questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.SUCCEED.getValue());
- questionSubmitUpdate.setJudgeInfo(JSONUtil.toJsonStr(judgeInfo));
- update = questionSubmitService.updateById(questionSubmitUpdate);
- if (!update) {
- throw new BusinessException(ResultCode.SYSTEM_ERROR, "题目状态更新错误");
- }
- QuestionSubmit questionSubmitResult = questionSubmitService.getById(questionId);
- return questionSubmitResult;
- }
- }
|