修复vjudge账号调度锁失效的bug
This commit is contained in:
parent
1d4f3ab9a2
commit
70cc10add1
|
@ -62,6 +62,12 @@ public class ChooseServer {
|
|||
.eq("is_remote", isRemote)
|
||||
.orderByAsc("task_number")
|
||||
.last("for update"); // 开启悲观锁
|
||||
/**
|
||||
* 如果一个条件无法通过索引快速过滤,存储引擎层面就会将所有记录加锁后返回,
|
||||
* 再由MySQL Server层进行过滤,但在实际使用过程当中,MySQL做了一些改进,
|
||||
* 在MySQL Server过滤条件,发现不满足后,会调用unlock_row方法,
|
||||
* 把不满足条件的记录释放锁 (违背了二段锁协议的约束)。
|
||||
*/
|
||||
List<JudgeServer> judgeServerList = judgeServerService.list(judgeServerQueryWrapper);
|
||||
// 获取可用判题机
|
||||
for (JudgeServer judgeServer : judgeServerList) {
|
||||
|
|
|
@ -4,17 +4,21 @@ import cn.hutool.json.JSONObject;
|
|||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import top.hcode.hoj.judge.Dispatcher;
|
||||
import top.hcode.hoj.pojo.entity.Judge;
|
||||
import top.hcode.hoj.pojo.entity.RemoteJudgeAccount;
|
||||
import top.hcode.hoj.pojo.entity.ToJudge;
|
||||
import top.hcode.hoj.service.impl.JudgeServiceImpl;
|
||||
import top.hcode.hoj.service.impl.ProblemServiceImpl;
|
||||
import top.hcode.hoj.service.impl.RemoteJudgeAccountServiceImpl;
|
||||
import top.hcode.hoj.utils.Constants;
|
||||
import top.hcode.hoj.utils.RedisUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -37,6 +41,9 @@ public class RemoteJudgeReceiver {
|
|||
@Autowired
|
||||
private RemoteJudgeAccountServiceImpl remoteJudgeAccountService;
|
||||
|
||||
@Resource
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Async("judgeTaskAsyncPool")
|
||||
public void processWaitingTask() {
|
||||
// 如果队列中还有任务,则继续处理
|
||||
|
@ -44,23 +51,33 @@ public class RemoteJudgeReceiver {
|
|||
String taskJsonStr = (String) redisUtils.lrPop(Constants.Judge.STATUS_REMOTE_JUDGE_WAITING_HANDLE.getName());
|
||||
// 再次检查
|
||||
if (taskJsonStr != null) {
|
||||
handleJudgeMsg(taskJsonStr);
|
||||
|
||||
JSONObject task = JSONUtil.parseObj(taskJsonStr);
|
||||
|
||||
Judge judge = task.get("judge", Judge.class);
|
||||
String token = task.getStr("token");
|
||||
String remoteJudgeProblem = task.getStr("remoteJudgeProblem");
|
||||
Boolean isContest = task.getBool("isContest");
|
||||
Integer tryAgainNum = task.getInt("tryAgainNum");
|
||||
Boolean isHasSubmitIdRemoteReJudge = task.getBool("isHasSubmitIdRemoteReJudge");
|
||||
|
||||
String remoteOJName = remoteJudgeProblem.split("-")[0].toUpperCase();
|
||||
|
||||
applicationContext.getBean(RemoteJudgeReceiver.class)
|
||||
.handleJudgeMsg(judge,
|
||||
token,
|
||||
remoteJudgeProblem,
|
||||
isContest,
|
||||
tryAgainNum,
|
||||
isHasSubmitIdRemoteReJudge,
|
||||
remoteOJName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleJudgeMsg(String taskJsonStr) {
|
||||
|
||||
JSONObject task = JSONUtil.parseObj(taskJsonStr);
|
||||
|
||||
Judge judge = task.get("judge", Judge.class);
|
||||
String token = task.getStr("token");
|
||||
String remoteJudgeProblem = task.getStr("remoteJudgeProblem");
|
||||
Boolean isContest = task.getBool("isContest");
|
||||
Integer tryAgainNum = task.getInt("tryAgainNum");
|
||||
Boolean isHasSubmitIdRemoteReJudge = task.getBool("isHasSubmitIdRemoteReJudge");
|
||||
|
||||
String remoteOJName = remoteJudgeProblem.split("-")[0].toUpperCase();
|
||||
@Transactional
|
||||
public void handleJudgeMsg(Judge judge, String token, String remoteJudgeProblem, Boolean isContest, Integer tryAgainNum,
|
||||
Boolean isHasSubmitIdRemoteReJudge, String remoteOJName) {
|
||||
|
||||
// 过滤出当前远程oj可用的账号列表
|
||||
QueryWrapper<RemoteJudgeAccount> remoteJudgeAccountQueryWrapper = new QueryWrapper<>();
|
||||
|
@ -83,6 +100,7 @@ public class RemoteJudgeReceiver {
|
|||
// POJ已有submitId的重判需要使用原来的账号获取结果
|
||||
if (isNeedAccountRejudge) {
|
||||
if (remoteJudgeAccount.getUsername().equals(judge.getVjudgeUsername())) {
|
||||
judge.setVjudgePassword(remoteJudgeAccount.getPassword()); // 避免账号改密码
|
||||
isHasAccountRejudge = true;
|
||||
remoteJudgeAccount.setStatus(false);
|
||||
boolean isOk = remoteJudgeAccountService.updateById(remoteJudgeAccount);
|
||||
|
|
|
@ -53,18 +53,18 @@ public class ConfigUtils {
|
|||
" port: " + configVo.getRedisPort() + "\n" +
|
||||
" password: " + configVo.getRedisPassword() + "\n" +
|
||||
" web-config:\n" +
|
||||
" base-url: " + UnicodeUtil.toUnicode(configVo.getBaseUrl()) + "\n" +
|
||||
" name: " + UnicodeUtil.toUnicode(configVo.getName()) + "\n" +
|
||||
" short-name: " + UnicodeUtil.toUnicode(configVo.getShortName()) + "\n" +
|
||||
" description: " + UnicodeUtil.toUnicode(configVo.getDescription(),true) + "\n" +
|
||||
" base-url: \"" + UnicodeUtil.toUnicode(configVo.getBaseUrl()) + "\"\n" +
|
||||
" name: \"" + UnicodeUtil.toUnicode(configVo.getName()) + "\"\n" +
|
||||
" short-name: \"" + UnicodeUtil.toUnicode(configVo.getShortName()) + "\"\n" +
|
||||
" description: \"" + UnicodeUtil.toUnicode(configVo.getDescription(),true) + "\"\n" +
|
||||
" register: " + configVo.getRegister() + "\n" +
|
||||
" footer:\n" +
|
||||
" record:\n" +
|
||||
" name: " + UnicodeUtil.toUnicode(configVo.getRecordName()) + "\n" +
|
||||
" url: " + UnicodeUtil.toUnicode(configVo.getRecordUrl()) + "\n" +
|
||||
" name: \"" + UnicodeUtil.toUnicode(configVo.getRecordName()) + "\"\n" +
|
||||
" url: \"" + UnicodeUtil.toUnicode(configVo.getRecordUrl()) + "\"\n" +
|
||||
" project:\n" +
|
||||
" name: " + UnicodeUtil.toUnicode(configVo.getProjectName()) + "\n" +
|
||||
" url: " + UnicodeUtil.toUnicode(configVo.getProjectUrl()) + "\n" +
|
||||
" name: \"" + UnicodeUtil.toUnicode(configVo.getProjectName()) + "\"\n" +
|
||||
" url: \"" + UnicodeUtil.toUnicode(configVo.getProjectUrl()) + "\"\n" +
|
||||
" hdu:\n" +
|
||||
" account:\n" +
|
||||
" username: " + listToStr(configVo.getHduUsernameList()) + "\n" +
|
||||
|
|
|
@ -170,6 +170,7 @@ public class HduJudge implements RemoteJudgeStrategy {
|
|||
put("Queuing", Constants.Judge.STATUS_PENDING);
|
||||
put("Running", Constants.Judge.STATUS_JUDGING);
|
||||
put("Compiling", Constants.Judge.STATUS_COMPILING);
|
||||
put("Runtime Error", Constants.Judge.STATUS_RUNTIME_ERROR);
|
||||
put("Time Limit Exceeded", Constants.Judge.STATUS_TIME_LIMIT_EXCEEDED);
|
||||
put("Memory Limit Exceeded", Constants.Judge.STATUS_MEMORY_LIMIT_EXCEEDED);
|
||||
put("Output Limit Exceeded", Constants.Judge.STATUS_RUNTIME_ERROR);
|
||||
|
|
|
@ -62,8 +62,8 @@ export const m = {
|
|||
Delete_User:'删除用户',
|
||||
Import_User: '导入用户',
|
||||
Import_User_Tips1:'用户数据导入仅支持csv格式的用户数据。',
|
||||
Import_User_Tips2:'共三列数据:用户名和密码不能为空,邮箱和真实姓名可选填,否则该行数据可能导入失败。',
|
||||
Import_User_Tips3:'第一行不必写(“用户名”,“密码”,“邮箱”,"真实姓名")这三个列名',
|
||||
Import_User_Tips2:'共四列数据:用户名和密码不能为空,邮箱和真实姓名可选填,否则该行数据可能导入失败。',
|
||||
Import_User_Tips3:'第一行不必写(“用户名”,“密码”,“邮箱”,"真实姓名")这四个列名',
|
||||
Import_User_Tips4:'请导入保存为UTF-8编码的文件,否则中文可能会乱码。',
|
||||
Choose_File:'选择文件',
|
||||
Password: '密码',
|
||||
|
|
|
@ -57,7 +57,7 @@ module.exports={
|
|||
port: 8088, // 开发服务器运行端口号
|
||||
proxy: {
|
||||
'/api': { // 以'/api'开头的请求会被代理进行转发
|
||||
target: 'http://localhost:6688', // 要发向的后台服务器地址 如果后台服务跑在后台开发人员的机器上,就写成 `http://ip:port` 如 `http:192.168.12.213:8081` ip为后台服务器的ip
|
||||
target: 'https://hdoi.cn', // 要发向的后台服务器地址 如果后台服务跑在后台开发人员的机器上,就写成 `http://ip:port` 如 `http:192.168.12.213:8081` ip为后台服务器的ip
|
||||
changeOrigin: true
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue