From ec727d58aa5593ef2aee756188bb36cddcb0846b Mon Sep 17 00:00:00 2001 From: masnn Date: Thu, 9 Apr 2020 22:56:22 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=84=E6=B5=8B=E5=88=97=E8=A1=A8=E5=AE=9E?= =?UTF-8?q?=E6=97=B6=E6=9B=B4=E6=96=B0&=E8=AF=84=E6=B5=8B=E6=9C=BA?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=9B=B4=E6=8D=A2=E4=B8=BAsocket?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hydro/handler/judge.js | 108 +++++++++++++++++++--------- hydro/handler/record.js | 10 ++- hydro/lib/mail.js | 2 +- templates/record_detail_status.html | 2 +- templates/record_main.html | 3 + templates/record_main_tr.html | 2 +- ui/pages/record_main.page.js | 6 ++ 7 files changed, 95 insertions(+), 38 deletions(-) diff --git a/hydro/handler/judge.js b/hydro/handler/judge.js index 4f6d6869..16b7001c 100644 --- a/hydro/handler/judge.js +++ b/hydro/handler/judge.js @@ -1,42 +1,21 @@ 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'); -GET('/judge/noop', requirePerm(PERM_JUDGE), async ctx => { - ctx.body = {}; -}); -GET('/judge/fetch', requirePerm(PERM_JUDGE), async ctx => { - let rid = await queue.get('judge', false); - if (rid) { - 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 - }; - ctx.body = { task }; - } - else ctx.body = {}; -}); -POST('/judge/next', requirePerm(PERM_JUDGE), async ctx => { - console.log(ctx.request.body); - let body = ctx.request.body; +async function next(body) { let rdoc = await record.get(body.rid); let $set = {}; if (body.case) { - rdoc.testCases.push(body.case); - $set.testCases = rdoc.testCases; + rdoc.cases.push(body.case); + $set.cases = rdoc.cases; } if (body.judge_text) { rdoc.judgeTexts.push(body.judge_text); @@ -52,22 +31,20 @@ POST('/judge/next', requirePerm(PERM_JUDGE), async ctx => { if (body.memory_kb) $set.memory = body.memory_kb; rdoc = await record.update(body.rid, $set); bus.publish('record_change', rdoc); - ctx.body = {}; -}); -POST('/judge/end', requirePerm(PERM_JUDGE), async ctx => { - let body = ctx.request.body; +} +async function end(body) { let rdoc = await record.get(body.rid); let $set = {}; if (body.case) { - rdoc.testCases.push(body.case); - $set.testCases = rdoc.testCases; + 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.compilerTexts); + rdoc.compilerTexts.push(body.compiler_text); $set.compilerTexts = rdoc.compilerTexts; } if (body.status) $set.status = body.status; @@ -75,8 +52,71 @@ POST('/judge/end', requirePerm(PERM_JUDGE), async ctx => { 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; + $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 = {}; +}); +GET('/judge/fetch', requirePerm(PERM_JUDGE), async ctx => { + let rid = await queue.get('judge', false); + if (rid) { + 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 + }; + ctx.body = { task }; + } + 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 => { + await next(ctx.request.body); + ctx.body = {}; +}); +POST('/judge/end', requirePerm(PERM_JUDGE), async ctx => { + 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 42a5767d..1bf35fc1 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 aa49cf2f..64557ef1 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 eda358ed..de7ad783 100644 --- a/templates/record_detail_status.html +++ b/templates/record_detail_status.html @@ -43,7 +43,7 @@ - {{ status.STATUS_TEXTS[rcdoc['status']] }} + {{ builtin.STATUS_TEXTS[rcdoc['status']] }} {{ rcdoc['judgeText'] }} diff --git a/templates/record_main.html b/templates/record_main.html index cd50d3ac..c22ca401 100644 --- a/templates/record_main.html +++ b/templates/record_main.html @@ -4,6 +4,9 @@
diff --git a/templates/record_main_tr.html b/templates/record_main_tr.html index 438c6264..64979d1d 100644 --- a/templates/record_main_tr.html +++ b/templates/record_main_tr.html @@ -26,5 +26,5 @@ {% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}≥{% endif %}{{ rdoc.time }}ms {% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}≥{% endif %}{{ rdoc.memory|format_size(1024) }} {{ builtin.LANG_TEXTS[rdoc['lang']] }} - {{ datetime_span(rdoc['_id'].generationTime)|safe }} + {{ datetime_span(rdoc['_id'])|safe }} diff --git a/ui/pages/record_main.page.js b/ui/pages/record_main.page.js index 4cc75b8c..54cfff5a 100644 --- a/ui/pages/record_main.page.js +++ b/ui/pages/record_main.page.js @@ -8,6 +8,12 @@ const page = new NamedPage('record_main', async () => { const sock = new SockJs(Context.socketUrl); const dd = new DiffDOM(); + sock.onopen = () => { + sock.send(document.cookie); + setTimeout(() => { + sock.send(JSON.stringify({ rdocs: Context.rids })); + }, 300); + }; sock.onmessage = (message) => { const msg = JSON.parse(message.data); const $newTr = $(msg.html);