Search in sources :

Example 1 with Judge

use of top.hcode.hoj.pojo.entity.judge.Judge in project HOJ by HimitZH.

the class JudgeController method submitProblemJudge.

@PostMapping(value = "/judge")
public CommonResult submitProblemJudge(@RequestBody ToJudge toJudge) {
    if (!toJudge.getToken().equals(judgeToken)) {
        return CommonResult.errorResponse("对不起!您使用的判题服务调用凭证不正确!访问受限!", CommonResult.STATUS_ACCESS_DENIED);
    }
    Judge judge = toJudge.getJudge();
    if (judge == null || judge.getSubmitId() == null || judge.getUid() == null || judge.getPid() == null) {
        return CommonResult.errorResponse("调用参数错误!请检查您的调用参数!", CommonResult.STATUS_FAIL);
    }
    // 标志该判题过程进入编译阶段
    judge.setStatus(Constants.Judge.STATUS_COMPILING.getStatus());
    // 写入当前判题服务的名字
    judge.setJudger(name);
    judgeService.updateById(judge);
    // 进行判题操作
    Problem problem = problemService.getById(judge.getPid());
    Judge finalJudge = judgeService.Judge(problem, judge);
    // 更新该次提交
    judgeService.updateById(finalJudge);
    if (finalJudge.getStatus().intValue() != Constants.Judge.STATUS_SUBMITTED_FAILED.getStatus()) {
        // 更新其它表
        judgeService.updateOtherTable(finalJudge.getSubmitId(), finalJudge.getStatus(), finalJudge.getCid(), finalJudge.getUid(), finalJudge.getPid(), finalJudge.getScore(), finalJudge.getTime());
    }
    return CommonResult.successResponse(finalJudge, "判题机评测完成!");
}
Also used : Problem(top.hcode.hoj.pojo.entity.problem.Problem) ToJudge(top.hcode.hoj.pojo.entity.judge.ToJudge) Judge(top.hcode.hoj.pojo.entity.judge.Judge)

Example 2 with Judge

use of top.hcode.hoj.pojo.entity.judge.Judge in project HOJ by HimitZH.

the class UserRecordServiceImpl method tryAgainUpdate.

@Transactional(isolation = Isolation.READ_COMMITTED)
public boolean tryAgainUpdate(String uid, Integer score) {
    boolean retryable;
    int attemptNumber = 0;
    do {
        // 查询最新版本号
        QueryWrapper<Judge> judgeQueryWrapper = new QueryWrapper<>();
        // 非比赛提交
        judgeQueryWrapper.isNotNull("score").orderByDesc("score").isNull("cid").last("limit 1");
        Judge lastHighScoreJudge = judgeService.getOne(judgeQueryWrapper);
        // 更新
        boolean success = true;
        if (lastHighScoreJudge == null) {
            UpdateWrapper<UserRecord> userRecordUpdateWrapper = new UpdateWrapper<>();
            userRecordUpdateWrapper.set("total_score", score).eq("uid", uid);
            success = userRecordMapper.update(null, userRecordUpdateWrapper) == 1;
        } else if (lastHighScoreJudge.getScore() < score) {
            // 如果之前该题目最高得分的提交比现在得分低,也需要修改
            int addValue = score - lastHighScoreJudge.getScore();
            UpdateWrapper<UserRecord> userRecordUpdateWrapper = new UpdateWrapper<>();
            userRecordUpdateWrapper.setSql("total_score=total_score+" + addValue).eq("uid", uid);
            success = userRecordMapper.update(null, userRecordUpdateWrapper) == 1;
        }
        if (success) {
            return true;
        } else {
            attemptNumber++;
            retryable = attemptNumber < 8;
            if (attemptNumber == 8) {
                log.error("更新user_record表超过最大重试次数");
                break;
            }
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                log.error(e.getMessage());
            }
        }
    } while (retryable);
    return false;
}
Also used : UserRecord(top.hcode.hoj.pojo.entity.user.UserRecord) UpdateWrapper(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) Judge(top.hcode.hoj.pojo.entity.judge.Judge) Transactional(org.springframework.transaction.annotation.Transactional)

Example 3 with Judge

use of top.hcode.hoj.pojo.entity.judge.Judge in project HOJ by HimitZH.

the class JudgeController method resubmit.

/**
 * @MethodName resubmit
 * @Params * @param null
 * @Description 调用判题服务器提交失败超过60s后,用户点击按钮重新提交判题进入的方法
 * @Return
 * @Since 2021/2/12
 */
@RequiresAuthentication
@GetMapping(value = "/resubmit")
@Transactional(rollbackFor = Exception.class)
public CommonResult resubmit(@RequestParam("submitId") Long submitId, HttpServletRequest request) {
    Judge judge = judgeService.getById(submitId);
    if (judge == null) {
        return CommonResult.errorResponse("此提交数据不存在!");
    }
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    if (!judge.getUid().equals(userRolesVo.getUid())) {
        // 不是本人无法重新提交
        return CommonResult.errorResponse("对不起!您并非提交数据的本人,无法重新提交!");
    }
    Problem problem = problemService.getById(judge.getPid());
    // 如果是非比赛题目
    if (judge.getCid() == 0) {
        // 如果该题已经是AC通过状态,更新该题目的用户ac做题表 user_acproblem
        if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus().intValue()) {
            QueryWrapper<UserAcproblem> userAcproblemQueryWrapper = new QueryWrapper<>();
            userAcproblemQueryWrapper.eq("submit_id", judge.getSubmitId());
            userAcproblemService.remove(userAcproblemQueryWrapper);
        }
    } else {
        if (problem.getIsRemote()) {
            // 将对应比赛记录设置成默认值
            UpdateWrapper<ContestRecord> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("submit_id", submitId).setSql("status=null,score=null");
            contestRecordService.update(updateWrapper);
        } else {
            return CommonResult.errorResponse("错误!非vJudge题目在比赛过程无权限重新提交");
        }
    }
    boolean isHasSubmitIdRemoteRejudge = false;
    if (Objects.nonNull(judge.getVjudgeSubmitId()) && (judge.getStatus().intValue() == Constants.Judge.STATUS_SUBMITTED_FAILED.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_PENDING.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_JUDGING.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_COMPILING.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_SYSTEM_ERROR.getStatus())) {
        isHasSubmitIdRemoteRejudge = true;
    }
    // 重新进入等待队列
    judge.setStatus(Constants.Judge.STATUS_PENDING.getStatus());
    judge.setVersion(judge.getVersion() + 1);
    judge.setErrorMessage(null).setOiRankScore(null).setScore(null).setTime(null).setJudger("").setMemory(null);
    judgeService.updateById(judge);
    // 将提交加入任务队列
    if (problem.getIsRemote()) {
        // 如果是远程oj判题
        remoteJudgeDispatcher.sendTask(judge, judgeToken, problem.getProblemId(), judge.getCid() != 0, isHasSubmitIdRemoteRejudge);
    } else {
        judgeDispatcher.sendTask(judge, judgeToken, judge.getCid() != 0);
    }
    return CommonResult.successResponse(judge, "重新提交成功!");
}
Also used : UpdateWrapper(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) ContestRecord(top.hcode.hoj.pojo.entity.contest.ContestRecord) Problem(top.hcode.hoj.pojo.entity.problem.Problem) UserAcproblem(top.hcode.hoj.pojo.entity.user.UserAcproblem) Judge(top.hcode.hoj.pojo.entity.judge.Judge) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication) Transactional(org.springframework.transaction.annotation.Transactional)

Example 4 with Judge

use of top.hcode.hoj.pojo.entity.judge.Judge in project HOJ by HimitZH.

the class JudgeController method checkCommonJudgeResult.

/**
 * @MethodName checkJudgeResult
 * @Params * @param null
 * @Description 对提交列表状态为Pending和Judging的提交进行更新检查
 * @Return
 * @Since 2021/1/3
 */
@RequestMapping(value = "/check-submissions-status", method = RequestMethod.POST)
public CommonResult checkCommonJudgeResult(@RequestBody SubmitIdListDto submitIdListDto) {
    List<Long> submitIds = submitIdListDto.getSubmitIds();
    if (CollectionUtils.isEmpty(submitIds)) {
        return CommonResult.successResponse(new HashMap<>(), "查询的提交id列表为空!");
    }
    QueryWrapper<Judge> queryWrapper = new QueryWrapper<>();
    // lambada表达式过滤掉code
    queryWrapper.select(Judge.class, info -> !info.getColumn().equals("code")).in("submit_id", submitIds);
    List<Judge> judgeList = judgeService.list(queryWrapper);
    HashMap<Long, Object> result = new HashMap<>();
    for (Judge judge : judgeList) {
        judge.setCode(null);
        judge.setErrorMessage(null);
        judge.setVjudgeUsername(null);
        judge.setVjudgeSubmitId(null);
        judge.setVjudgePassword(null);
        result.put(judge.getSubmitId(), judge);
    }
    return CommonResult.successResponse(result, "获取最新判题数据成功!");
}
Also used : java.util(java.util) UpdateWrapper(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper) Problem(top.hcode.hoj.pojo.entity.problem.Problem) TrainingRecordServiceImpl(top.hcode.hoj.service.training.impl.TrainingRecordServiceImpl) ContestRecord(top.hcode.hoj.pojo.entity.contest.ContestRecord) JudgeVo(top.hcode.hoj.pojo.vo.JudgeVo) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) RemoteJudgeDispatcher(top.hcode.hoj.judge.remote.RemoteJudgeDispatcher) Autowired(org.springframework.beans.factory.annotation.Autowired) RedisUtils(top.hcode.hoj.utils.RedisUtils) CommonResult(top.hcode.hoj.common.result.CommonResult) RefreshScope(org.springframework.cloud.context.config.annotation.RefreshScope) Value(org.springframework.beans.factory.annotation.Value) Judge(top.hcode.hoj.pojo.entity.judge.Judge) RequiresPermissions(org.apache.shiro.authz.annotation.RequiresPermissions) HttpServletRequest(javax.servlet.http.HttpServletRequest) ProblemService(top.hcode.hoj.service.problem.ProblemService) JudgeCaseServiceImpl(top.hcode.hoj.service.judge.impl.JudgeCaseServiceImpl) ContestRecordServiceImpl(top.hcode.hoj.service.contest.impl.ContestRecordServiceImpl) JudgeServiceImpl(top.hcode.hoj.service.judge.impl.JudgeServiceImpl) JudgeCase(top.hcode.hoj.pojo.entity.judge.JudgeCase) JudgeDispatcher(top.hcode.hoj.judge.self.JudgeDispatcher) HttpSession(javax.servlet.http.HttpSession) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) IpUtils(top.hcode.hoj.utils.IpUtils) Contest(top.hcode.hoj.pojo.entity.contest.Contest) SubmitIdListDto(top.hcode.hoj.pojo.dto.SubmitIdListDto) UserAcproblem(top.hcode.hoj.pojo.entity.user.UserAcproblem) CollectionUtils(org.springframework.util.CollectionUtils) org.springframework.web.bind.annotation(org.springframework.web.bind.annotation) ToJudgeDto(top.hcode.hoj.pojo.dto.ToJudgeDto) ContestServiceImpl(top.hcode.hoj.service.contest.impl.ContestServiceImpl) Constants(top.hcode.hoj.utils.Constants) UserAcproblemServiceImpl(top.hcode.hoj.service.user.impl.UserAcproblemServiceImpl) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication) IPage(com.baomidou.mybatisplus.core.metadata.IPage) SecurityUtils(org.apache.shiro.SecurityUtils) Transactional(org.springframework.transaction.annotation.Transactional) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) Judge(top.hcode.hoj.pojo.entity.judge.Judge)

Example 5 with Judge

use of top.hcode.hoj.pojo.entity.judge.Judge in project HOJ by HimitZH.

the class JudgeController method submitProblemJudge.

/**
 * @MethodName submitProblemJudge
 * @Params * @param null
 * @Description 核心方法 判题通过openfeign调用判题系统服务
 * @Return CommonResult
 * @Since 2020/10/30
 */
@RequiresAuthentication
@RequiresPermissions("submit")
@RequestMapping(value = "/submit-problem-judge", method = RequestMethod.POST)
@Transactional(rollbackFor = Exception.class)
public CommonResult submitProblemJudge(@RequestBody ToJudgeDto judgeDto, HttpServletRequest request) {
    CommonResult checkResult = judgeService.checkSubmissionInfo(judgeDto);
    if (checkResult != null) {
        return checkResult;
    }
    // 需要获取一下该token对应用户的数据
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    boolean isContestSubmission = judgeDto.getCid() != 0;
    boolean isTrainingSubmission = judgeDto.getTid() != null && judgeDto.getTid() != 0;
    if (!isContestSubmission) {
        // 非比赛提交限制8秒提交一次
        String lockKey = Constants.Account.SUBMIT_NON_CONTEST_LOCK.getCode() + userRolesVo.getUid();
        long count = redisUtils.incr(lockKey, 1);
        if (count > 1) {
            return CommonResult.errorResponse("对不起,您的提交频率过快,请稍后再尝试!", CommonResult.STATUS_FORBIDDEN);
        }
        redisUtils.expire(lockKey, 8);
    }
    // 将提交先写入数据库,准备调用判题服务器
    Judge judge = new Judge();
    // 默认设置代码为单独自己可见
    judge.setShare(false).setCode(judgeDto.getCode()).setCid(judgeDto.getCid()).setLanguage(judgeDto.getLanguage()).setLength(judgeDto.getCode().length()).setUid(userRolesVo.getUid()).setUsername(userRolesVo.getUsername()).setStatus(// 开始进入判题队列
    Constants.Judge.STATUS_PENDING.getStatus()).setSubmitTime(new Date()).setVersion(0).setIp(IpUtils.getUserIpAddr(request));
    CommonResult result = null;
    // 如果比赛id不等于0,则说明为比赛提交
    if (isContestSubmission) {
        result = contestRecordService.submitContestProblem(judgeDto, userRolesVo, judge);
    } else if (isTrainingSubmission) {
        result = trainingRecordService.submitTrainingProblem(judgeDto, userRolesVo, judge);
    } else {
        // 如果不是比赛提交和训练提交
        result = judgeService.submitProblem(judgeDto, judge);
    }
    if (result != null) {
        return result;
    }
    // 将提交加入任务队列
    if (judgeDto.getIsRemote()) {
        // 如果是远程oj判题
        remoteJudgeDispatcher.sendTask(judge, judgeToken, judge.getDisplayPid(), isContestSubmission, false);
    } else {
        judgeDispatcher.sendTask(judge, judgeToken, isContestSubmission);
    }
    return CommonResult.successResponse(judge, "代码提交成功!");
}
Also used : HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) CommonResult(top.hcode.hoj.common.result.CommonResult) Judge(top.hcode.hoj.pojo.entity.judge.Judge) RequiresPermissions(org.apache.shiro.authz.annotation.RequiresPermissions) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication) Transactional(org.springframework.transaction.annotation.Transactional)

Aggregations

Judge (top.hcode.hoj.pojo.entity.judge.Judge)50 QueryWrapper (com.baomidou.mybatisplus.core.conditions.query.QueryWrapper)29 UpdateWrapper (com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper)21 Transactional (org.springframework.transaction.annotation.Transactional)18 Problem (top.hcode.hoj.pojo.entity.problem.Problem)18 UserRolesVo (top.hcode.hoj.pojo.vo.UserRolesVo)14 Contest (top.hcode.hoj.pojo.entity.contest.Contest)13 Session (org.apache.shiro.session.Session)11 HttpSession (javax.servlet.http.HttpSession)10 ContestRecord (top.hcode.hoj.pojo.entity.contest.ContestRecord)10 JudgeCase (top.hcode.hoj.pojo.entity.judge.JudgeCase)10 RequiresAuthentication (org.apache.shiro.authz.annotation.RequiresAuthentication)8 UserAcproblem (top.hcode.hoj.pojo.entity.user.UserAcproblem)8 StatusFailException (top.hcode.hoj.common.exception.StatusFailException)7 java.util (java.util)6 HttpServletRequest (javax.servlet.http.HttpServletRequest)6 SecurityUtils (org.apache.shiro.SecurityUtils)6 Autowired (org.springframework.beans.factory.annotation.Autowired)6 Constants (top.hcode.hoj.utils.Constants)6 JSONObject (cn.hutool.json.JSONObject)4