From 4c53fc8146f6c1418dc7952df52eb6375ab31019 Mon Sep 17 00:00:00 2001 From: masnn Date: Thu, 9 Apr 2020 18:11:56 +0800 Subject: [PATCH] fix rejudge, add cache --- hydro/handler/base.js | 6 +++- hydro/handler/record.js | 77 +++++++++++++++++++---------------------- hydro/handler/ui.js | 15 +++----- hydro/model/record.js | 16 ++++++++- hydro/service/server.js | 21 +++++------ package.json | 2 +- yarn.lock | 69 ++++++++++++++++++------------------ 7 files changed, 103 insertions(+), 103 deletions(-) diff --git a/hydro/handler/base.js b/hydro/handler/base.js index 78037b90..826204e6 100644 --- a/hydro/handler/base.js +++ b/hydro/handler/base.js @@ -44,6 +44,10 @@ MIDDLEWARE(async (ctx, next) => { } } }; + ctx.back = () => { + console.log(122143); + ctx.redirect(ctx.request.headers.referer || '/'); + }; ctx.csrf_token = await token.add(token.TYPE_CSRF_TOKEN, 600, ctx.path); await next(); if (ctx.session.sid) @@ -58,7 +62,7 @@ MIDDLEWARE(async (ctx, next) => { update_ip: ctx.request.ip, update_ua: ctx.request.headers['user-agent'] || '' }, ctx.session)); - let cookie = { secure: options.session.secure, httponly: true }; + let cookie = { secure: options.session.secure }; if (save) { cookie.expires = ctx.session.expireAt, cookie.maxAge = expireSeconds; ctx.cookies.set('save', 'true', cookie); diff --git a/hydro/handler/record.js b/hydro/handler/record.js index 89cb5d58..489d1f28 100644 --- a/hydro/handler/record.js +++ b/hydro/handler/record.js @@ -23,26 +23,19 @@ GET('/r', async ctx => { } ctx.body = { page, rdocs, pdict, udict }; }); -SOCKET('/record-conn', class RecordConnHandler { - constructor(conn) { - this.tid = null; - this.h = async data => { - let rdoc = data.value; - if (rdoc.tid && rdoc.tid != this.tid.toString()) return; - let [udoc, pdoc] = await Promise.all([user.getById(rdoc.uid), problem.get({ pid: rdoc.pid })]); - if (pdoc.hidden && !conn.state.user.hasPerm(PERM_VIEW_PROBLEM_HIDDEN)) pdoc = null; - conn.send({ html: await conn.renderHTML('record_main_tr.html', { rdoc, udoc, pdoc }) }); - }; - } - onOpen() { - bus.subscribe(['record_change'], this.h); - } - onMessage(data) { - if (data.tid) this.tid = data.tid; - } - onClose() { - bus.unsubscribe(['record_change'], this.h); +SOCKET('/record-conn', [], conn => { + let tid = conn.params.tid; + async function onRecordChange(data) { + let rdoc = data.value; + if (rdoc.tid && rdoc.tid.toString() != tid) return; + let [udoc, pdoc] = await Promise.all([user.getById(rdoc.uid), problem.get({ pid: rdoc.pid })]); + if (pdoc.hidden && !conn.state.user.hasPerm(PERM_VIEW_PROBLEM_HIDDEN)) pdoc = null; + conn.send({ html: await conn.renderHTML('record_main_tr.html', { rdoc, udoc, pdoc }) }); } + bus.subscribe(['record_change'], onRecordChange); + conn.on('close', () => { + bus.unsubscribe(['record_change'], onRecordChange); + }); }); GET('/r/:rid', async ctx => { ctx.templateName = 'record_detail.html'; @@ -52,35 +45,37 @@ GET('/r/:rid', async ctx => { if (rdoc.uid != uid && !ctx.state.user.hasPerm(PERM_READ_RECORD_CODE)) rdoc.code = null; ctx.body = { rdoc, show_status: true }; }); -SOCKET('/record-detail-conn', class RecordDetailConnHandler { - constructor(conn) { - this.rid = conn.params.rid; - this.h = async data => { - let rdoc = data.value; - if (rdoc.rid.toString() != this.rid) return; - let [udoc, pdoc] = await Promise.all([user.getById(rdoc.uid), problem.get({ pid: rdoc.pid })]); - if (pdoc.hidden && !conn.state.user.hasPerm(PERM_VIEW_PROBLEM_HIDDEN)) pdoc = null; - conn.send({ html: await conn.renderHTML('record_main_tr.html', { rdoc, udoc, pdoc }) }); - }; - } - async onOpen() { - bus.subscribe(['record_change'], this.h); - } - onMessage(data) { - if (data.rid) this.rid = data.rid; - } - onClose() { - bus.unsubscribe(['record_change'], this.h); +SOCKET('/record-detail-conn', [], async conn => { + let rdoc = await record.get(conn.params.rid); + if (rdoc.tid) + if (!await conn.rdoc_contest_visible(rdoc)) { + conn.close(); + return; + } + async function onRecordChange(data) { + let rdoc = data.value; + if (rdoc._id.toString() != conn.params.rid) return; + conn.send({ + status_html: await conn.renderHTML('record_detail_status.html', { rdoc }), + summary_html: await conn.renderHTML('record_detail_summary.html', { rdoc }) + }); } + bus.subscribe(['record_change'], onRecordChange); + onRecordChange({ value: rdoc }); + conn.on('close', () => { + bus.unsubscribe(['record_change'], onRecordChange); + }); }); POST('/r/:rid/rejudge', requirePerm(PERM_REJUDGE), async ctx => { - ctx.templateName = 'record_detail.html'; let uid = ctx.state.user._id, rid = new bson.ObjectID(ctx.params.rid); let rdoc = await record.get(rid); if (rdoc.hidden) ctx.checkPerm(PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD); if (rdoc.uid != uid && !ctx.state.user.hasPerm(PERM_READ_RECORD_CODE)) rdoc.code = null; - if (rdoc) await queue.push('judge', rid); - ctx.body = { rdoc, show_status: true }; + if (rdoc) { + await record.reset(rid); + await queue.push('judge', rid); + } + ctx.back(); }); /* diff --git a/hydro/handler/ui.js b/hydro/handler/ui.js index bf614d7a..64217478 100644 --- a/hydro/handler/ui.js +++ b/hydro/handler/ui.js @@ -1,6 +1,6 @@ const path = require('path'), - send = require('koa-send'), + staticCache = require('koa-static-cache'), nunjucks = require('nunjucks'), hljs = require('highlight.js'), MarkdownIt = require('markdown-it'), @@ -77,16 +77,9 @@ class Nunjucks extends nunjucks.Environment { } } let env = new Nunjucks(); -MIDDLEWARE(async (ctx, next) => { - let done = false; - if (ctx.method === 'HEAD' || ctx.method === 'GET') - try { - done = await send(ctx, ctx.path, { root: path.resolve(process.cwd(), '.uibuild'), index: 'index.html' }); - } catch (err) { - if (err.status !== 404) throw err; - } - if (!done) await next(); -}); +MIDDLEWARE(staticCache(path.join(process.cwd(), '.uibuild'), { + maxAge: 365 * 24 * 60 * 60 +})); MIDDLEWARE(async (ctx, next) => { ctx.render_title = str => str; ctx.UIContext = { diff --git a/hydro/model/record.js b/hydro/model/record.js index f058f5ab..7f0fa0e6 100644 --- a/hydro/model/record.js +++ b/hydro/model/record.js @@ -45,6 +45,19 @@ async function update(rid, $set) { if (!rdoc) throw new RecordNotFoundError(rid); return rdoc; } +async function reset(rid) { + return await update(rid, { + score: 0, + status: STATUS_WAITING, + time: 0, + memory: 0, + cases: [], + judgeTexts: [], + compilerTexts: [], + judgeAt: null, + judger: null + }); +} async function count(query) { return await coll.find(query).count(); } @@ -54,5 +67,6 @@ module.exports = { get, getMany, update, - count + count, + reset }; \ No newline at end of file diff --git a/hydro/service/server.js b/hydro/service/server.js index 6ad78429..9ab2056d 100644 --- a/hydro/service/server.js +++ b/hydro/service/server.js @@ -41,19 +41,16 @@ function GET(route, ...handler) { function POST(route, ...handler) { router.post(route, ...handler); } -/** - * @callback SocketIOHandler - * @param {import('socket.io').Socket} socket - */ + /** * @callback SockJSHandler * @param {import('sockjs').Connection} conn */ /** * @param {string} prefix - * @param {SocketIOHandler} handler + * @param {SockJSHandler} handler */ -function SOCKET(prefix, handler) { +function SOCKET(prefix, middlewares, handler) { const sock = sockjs.createServer({ prefix }); sock.on('connection', async conn => { conn.cookies = { @@ -80,18 +77,18 @@ function SOCKET(prefix, handler) { }); setTimeout(reject, 5000); }); - for (let i of m) { + for (let i of m) + await new Promise((resolve, reject) => { + i(conn, resolve).catch(reject); + }); + for (let i of middlewares) await new Promise((resolve, reject) => { i(conn, resolve).catch(reject); }); - } conn.send = data => { conn.write(JSON.stringify(data)); }; - let h = new handler(conn); - if (h.onOpen) conn.on('open', h.onOpen); - if (h.onClose) conn.on('close', h.onClose); - if (h.onMessage) conn.on('data', h.onMessage); + handler(conn); }); sock.installHandlers(server); } diff --git a/package.json b/package.json index e90a34e8..dd9b9ee4 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "koa-body": "^4.1.1", "koa-morgan": "^1.0.1", "koa-router": "^7.4.0", - "koa-send": "^5.0.0", + "koa-static-cache": "^5.1.2", "lodash": "^4.17.15", "markdown-it": "^10.0.0", "markdown-it-katex": "^2.0.3", diff --git a/yarn.lock b/yarn.lock index 6bfd1d08..2e3947f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -288,6 +288,13 @@ commander@^3.0.2: resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== +compressible@^2.0.6: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -623,6 +630,11 @@ fresh@~0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +fs-readdir-recursive@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -698,16 +710,6 @@ http-errors@1.7.3, http-errors@^1.3.1, http-errors@^1.6.3, http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - "http-parser-js@>=0.4.0 <0.4.11": version "0.4.10" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" @@ -761,11 +763,6 @@ inherits@2, inherits@2.0.4, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - inquirer@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" @@ -934,15 +931,16 @@ koa-router@^7.4.0: path-to-regexp "^1.1.1" urijs "^1.19.0" -koa-send@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.0.tgz#5e8441e07ef55737734d7ced25b842e50646e7eb" - integrity sha512-90ZotV7t0p3uN9sRwW2D484rAaKIsD8tAVtypw/aBU+ryfV+fR2xrcAwhI8Wl6WRkojLUs/cB9SBSCuIb+IanQ== +koa-static-cache@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/koa-static-cache/-/koa-static-cache-5.1.2.tgz#49b592007157b164f5e9df5b276e305c8be5016a" + integrity sha512-EhnVBF9mkbp7bijDz2+yg5KxXFsUYUQCOqGy78bAhJp2PRMCMYV7nG/f7k9/liw+43u2Uow0v6ZZ025qBCYsGw== dependencies: + compressible "^2.0.6" debug "^3.1.0" - http-errors "^1.6.3" + fs-readdir-recursive "^1.0.0" + mime-types "^2.1.8" mz "^2.7.0" - resolve-path "^1.4.0" koa@^2.11.0: version "2.11.0" @@ -1047,6 +1045,11 @@ mime-db@1.42.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== +mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + mime-types@^2.1.18, mime-types@~2.1.24: version "2.1.25" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" @@ -1054,6 +1057,13 @@ mime-types@^2.1.18, mime-types@~2.1.24: dependencies: mime-db "1.42.0" +mime-types@^2.1.8: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + dependencies: + mime-db "1.43.0" + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -1227,7 +1237,7 @@ parseurl@^1.3.2: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -path-is-absolute@1.0.1, path-is-absolute@^1.0.0: +path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= @@ -1327,14 +1337,6 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-path@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" - integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc= - dependencies: - http-errors "~1.6.2" - path-is-absolute "1.0.1" - restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" @@ -1396,11 +1398,6 @@ semver@^6.1.2: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - setprototypeof@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" @@ -1453,7 +1450,7 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0: +"statuses@>= 1.5.0 < 2", statuses@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=