diff --git a/hydro/handler/judge.js b/hydro/handler/judge.js index 4f6d68695..16b7001c9 100644 --- a/hydro/handler/judge.js +++ b/hydro/handler/judge.js @@ -1,14 +1,62 @@ const { requirePerm } = require('./tools'), + { sleep } = require('../utils'), { PERM_JUDGE } = require('../permission'), record = require('../model/record'), problem = require('../model/problem'), bus = require('../service/bus'), queue = require('../service/queue'), - { GET, POST } = require('../service/server'); + { GET, POST, SOCKET } = require('../service/server'); queue.assert('judge'); +async function next(body) { + let rdoc = await record.get(body.rid); + let $set = {}; + if (body.case) { + rdoc.cases.push(body.case); + $set.cases = rdoc.cases; + } + if (body.judge_text) { + rdoc.judgeTexts.push(body.judge_text); + $set.judgeTexts = rdoc.judgeTexts; + } + if (body.compiler_text) { + rdoc.compilerTexts.push(body.compiler_text); + $set.compilerTexts = rdoc.compilerTexts; + } + if (body.status) $set.status = body.status; + if (body.score) $set.score = body.score; + if (body.time_ms) $set.time = body.time_ms; + if (body.memory_kb) $set.memory = body.memory_kb; + rdoc = await record.update(body.rid, $set); + bus.publish('record_change', rdoc); +} +async function end(body) { + let rdoc = await record.get(body.rid); + let $set = {}; + if (body.case) { + rdoc.cases.push(body.case); + $set.cases = rdoc.cases; + } + if (body.judge_text) { + rdoc.judgeTexts.push(body.judge_text); + $set.judgeTexts = rdoc.judgeTexts; + } + if (body.compiler_text) { + rdoc.compilerTexts.push(body.compiler_text); + $set.compilerTexts = rdoc.compilerTexts; + } + if (body.status) $set.status = body.status; + if (body.score) $set.score = body.score; + if (body.time_ms) $set.time = body.time_ms; + if (body.memory_kb) $set.memory = body.memory_kb; + $set.judgeAt = new Date(); + $set.judger = body.judger; + rdoc = await record.update(body.rid, $set); + bus.publish('record_change', rdoc); +} + GET('/judge/noop', requirePerm(PERM_JUDGE), async ctx => { ctx.body = {}; }); @@ -29,54 +77,46 @@ GET('/judge/fetch', requirePerm(PERM_JUDGE), async ctx => { } else ctx.body = {}; }); +SOCKET('/judge/conn', [requirePerm(PERM_JUDGE)], async conn => { + let isOpen = true, processing = null; + conn.on('close', async () => { + isOpen = false; + if (processing) { + await record.reset(processing); + queue.push('judge', processing); + } + }); + conn.on('data', async message => { + message = JSON.parse(message); + if (message.key == 'next') await next(message); + else if (message.key == 'end') { + await end(Object.assign({ judger: conn.state.user._id }, message)); + processing = null; + } + }); + while (isOpen) { + if (!processing) { + let rid = await queue.get('judge'); + let rdoc = await record.get(rid); + let pdoc = await problem.getById(rdoc.pid); + let task = { + event: 'judge', + rid, type: 0, + pid: rdoc.pid, + data: pdoc.data, + lang: rdoc.lang, + code: rdoc.code + }; + conn.write(JSON.stringify({ task })); + processing = task.rid; + } else await sleep(100); + } +}); POST('/judge/next', requirePerm(PERM_JUDGE), async ctx => { - console.log(ctx.request.body); - let body = ctx.request.body; - let rdoc = await record.get(body.rid); - let $set = {}; - if (body.case) { - rdoc.testCases.push(body.case); - $set.testCases = rdoc.testCases; - } - if (body.judge_text) { - rdoc.judgeTexts.push(body.judge_text); - $set.judgeTexts = rdoc.judgeTexts; - } - if (body.compiler_text) { - rdoc.compilerTexts.push(body.compiler_text); - $set.compilerTexts = rdoc.compilerTexts; - } - if (body.status) $set.status = body.status; - if (body.score) $set.score = body.score; - if (body.time_ms) $set.time = body.time_ms; - if (body.memory_kb) $set.memory = body.memory_kb; - rdoc = await record.update(body.rid, $set); - bus.publish('record_change', rdoc); + await next(ctx.request.body); ctx.body = {}; }); POST('/judge/end', requirePerm(PERM_JUDGE), async ctx => { - let body = ctx.request.body; - let rdoc = await record.get(body.rid); - let $set = {}; - if (body.case) { - rdoc.testCases.push(body.case); - $set.testCases = rdoc.testCases; - } - if (body.judge_text) { - rdoc.judgeTexts.push(body.judge_text); - $set.judgeTexts = rdoc.judgeTexts; - } - if (body.compiler_text) { - rdoc.compilerTexts.push(body.compilerTexts); - $set.compilerTexts = rdoc.compilerTexts; - } - if (body.status) $set.status = body.status; - if (body.score) $set.score = body.score; - if (body.time_ms) $set.time = body.time_ms; - if (body.memory_kb) $set.memory = body.memory_kb; - $set.judgeAt = new Date(); - $set.judger = ctx.state.user._id; - rdoc = await record.update(body.rid, $set); - bus.publish('record_change', rdoc); + await end(Object.assign({ judger: ctx.state.user._id }, ctx.request.body)); ctx.body = {}; }); diff --git a/hydro/handler/record.js b/hydro/handler/record.js index 42a5767d2..1bf35fc1c 100644 --- a/hydro/handler/record.js +++ b/hydro/handler/record.js @@ -15,7 +15,7 @@ GET('/r', async ctx => { ctx.templateName = 'record_main.html'; let q = {}, page = ctx.query.page || 1; - let rdocs = await record.getMany(q, { rid: 1 }, page, constants.RECORD_PER_PAGE); + let rdocs = await record.getMany(q, { _id: -1 }, page, constants.RECORD_PER_PAGE); let pdict = {}, udict = {}; for (let rdoc of rdocs) { udict[rdoc.uid] = await user.getById(rdoc.uid); @@ -39,6 +39,14 @@ SOCKET('/record-conn', [], conn => { conn.send({ html: await conn.renderHTML('record_main_tr.html', { rdoc, udoc, pdoc }) }); } bus.subscribe(['record_change'], onRecordChange); + conn.on('data', async message => { + console.log(message); + let { rids } = JSON.parse(message); + for (let rid of rids) { + let rdoc = await record.get(rid); + await onRecordChange({ value: rdoc }); + } + }); conn.on('close', () => { bus.unsubscribe(['record_change'], onRecordChange); }); diff --git a/hydro/lib/mail.js b/hydro/lib/mail.js index aa49cf2f8..64557ef1c 100644 --- a/hydro/lib/mail.js +++ b/hydro/lib/mail.js @@ -25,7 +25,7 @@ module.exports = { * @param {string} text * @param {string} html */ - async send_mail(to, subject, text, html) { + async sendMail(to, subject, text, html) { let t; try { t = await new Promise((resolve, reject) => { diff --git a/templates/record_detail_status.html b/templates/record_detail_status.html index eda358ed3..de7ad7835 100644 --- a/templates/record_detail_status.html +++ b/templates/record_detail_status.html @@ -43,7 +43,7 @@