package cn.seecoder.ojserver.service.impl; import cn.seecoder.codejudge.client.CodeJudgeException; import cn.seecoder.codejudge.client.JudgeDTO; import cn.seecoder.codejudge.client.JudgeResult; import cn.seecoder.codejudge.client.JudgeResultType; import cn.seecoder.ojserver.dao.CommitDAO; import cn.seecoder.ojserver.dao.entity.Commit; import cn.seecoder.ojserver.dao.entity.Problem; import cn.seecoder.ojserver.dao.entity.TestCase; import cn.seecoder.ojserver.enums.CodeJudgeResultType; import cn.seecoder.ojserver.exception.ThirdPartyServiceException; import cn.seecoder.ojserver.manager.JudgeManager; import cn.seecoder.ojserver.manager.QuestionManager; import cn.seecoder.ojserver.model.dto.CodeJudgeDTO; import cn.seecoder.ojserver.model.vo.CodeJudgeVO; import cn.seecoder.ojserver.service.JudgeService; import okhttp3.*; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.stereotype.Service; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Service public class JudgeServiceImpl implements JudgeService { private final QuestionManager questionManager; private final JudgeManager judgeManager; private final OkHttpClient client; private final RabbitTemplate rabbitTemplate; private final CommitDAO commitDAO; public JudgeServiceImpl(QuestionManager questionManager, JudgeManager judgeManager, RabbitTemplate rabbitTemplate, CommitDAO commitDAO) { this.questionManager = questionManager; this.judgeManager = judgeManager; this.client = new OkHttpClient() .newBuilder() .connectTimeout(60000, TimeUnit.MILLISECONDS) .readTimeout(60000, TimeUnit.MILLISECONDS) .build(); this.rabbitTemplate = rabbitTemplate; this.commitDAO = commitDAO; } @Override public JudgeResult judgeCode(Integer questionId, CodeJudgeVO codeJudgeVO) { try { JudgeDTO judgeDTO = new JudgeDTO(); judgeDTO.setCode(codeJudgeVO.getCode()); judgeDTO.setLanguage(codeJudgeVO.getLanguage()); Problem problem = questionManager.getProblemById(questionId).get(); List testCaseList = questionManager.getTestCaseByProblemId(questionId); judgeDTO.setMemoryLimit(problem.getMemoryLimit()); judgeDTO.setTimeLimit(problem.getTimeLimit()); List inputList = testCaseList.stream().map(TestCase::getInput).collect(Collectors.toList()); List outputList = testCaseList.stream().map(TestCase::getOutput).collect(Collectors.toList()); judgeDTO.setInputList(inputList); judgeDTO.setOutputList(outputList); return judgeManager.judgeCodeQuestionAnswers(judgeDTO); } catch (ThirdPartyServiceException exception) { throw exception; } } @Override public JudgeResult asyncJudgeCode(Integer questionId, CodeJudgeVO codeJudgeVO) { Commit commit = new Commit(); commit.setUserId(0); commit.setProblemId(questionId); commit.setCode(codeJudgeVO.getCode()); commit.setLanguage(codeJudgeVO.getLanguage()); commit.setCommitTime(new Date()); commitDAO.save(commit); CodeJudgeDTO codeJudgeDTO = new CodeJudgeDTO(commit.getId(), questionId, codeJudgeVO); rabbitTemplate.convertAndSend("notice_queue", codeJudgeDTO); return null; } @Override public JudgeResult syncJudgeCode(Integer questionId, CodeJudgeVO codeJudgeVO) { Commit commit = new Commit(); commit.setUserId(0); commit.setProblemId(questionId); commit.setCode(codeJudgeVO.getCode()); commit.setLanguage(codeJudgeVO.getLanguage()); commit.setCommitTime(new Date()); JudgeResult judgeResult = judgeCode(questionId, codeJudgeVO); CodeJudgeResultType message = CodeJudgeResultType.values()[JudgeResultType.ACCEPT.ordinal()]; for (JudgeResult.Item item : judgeResult.getResultList()) { if (item.getResult() != JudgeResultType.ACCEPT) { message = CodeJudgeResultType.values()[item.getResult().ordinal()]; break; } } int acNum = 0; for (JudgeResult.Item item : judgeResult.getResultList()) { if (item.getResult() == JudgeResultType.ACCEPT) { acNum++; } } int score = (acNum / judgeResult.getResultList().size()) * 100; commit.setResult(message.name()); commit.setScore(score); commit.setJudgeTime(new Date()); commitDAO.save(commit); return judgeResult; } @Override public JudgeResult rabbit(Integer questionId, CodeJudgeVO codeJudgeVO) { CodeJudgeDTO codeJudgeDTO = new CodeJudgeDTO(1, questionId, codeJudgeVO); rabbitTemplate.convertAndSend("test_queue", codeJudgeDTO); return null; } @Override public JudgeResult mysqlAndMQ(Integer questionId, CodeJudgeVO codeJudgeVO) { Commit commit = new Commit(); commit.setUserId(0); commit.setProblemId(questionId); commit.setCode(codeJudgeVO.getCode()); commit.setLanguage(codeJudgeVO.getLanguage()); commit.setCommitTime(new Date()); commitDAO.save(commit); CodeJudgeDTO codeJudgeDTO = new CodeJudgeDTO(commit.getId(), questionId, codeJudgeVO); rabbitTemplate.convertAndSend("test_queue", codeJudgeDTO); return null; } }