From 73aa641258db3ff3c1279141badca23ad7be6e0d Mon Sep 17 00:00:00 2001 From: undefined Date: Sun, 27 Nov 2022 16:16:21 +0800 Subject: [PATCH] core&ui: performance optimization --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/record.ts | 2 +- packages/hydrooj/src/handler/training.ts | 22 +++++++++++-------- packages/hydrooj/src/model/domain.ts | 4 ++++ packages/hydrooj/src/service/storage.ts | 3 ++- packages/ui-default/package.json | 2 +- .../ui-default/templates/training_detail.html | 18 +++++++-------- 7 files changed, 31 insertions(+), 22 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index c015d5454..c80fa919a 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "4.4.0", + "version": "4.4.1", "bin": "bin/hydrooj.js", "main": "src/plugin-api", "module": "src/plugin-api", diff --git a/packages/hydrooj/src/handler/record.ts b/packages/hydrooj/src/handler/record.ts index 6a399224f..f2e4092e1 100644 --- a/packages/hydrooj/src/handler/record.ts +++ b/packages/hydrooj/src/handler/record.ts @@ -171,7 +171,7 @@ class RecordDetailHandler extends ContestDetailBaseHandler { canViewCode ||= tsdoc?.attend; } if (!tsdoc?.attend && !problem.canViewBy(pdoc, this.user)) throw new PermissionError(PERM.PERM_VIEW_PROBLEM_HIDDEN); - } else if (!problem.canViewBy(pdoc, this.user)) throw new PermissionError(PERM.PERM_VIEW_PROBLEM_HIDDEN); + } else if (pdoc && !problem.canViewBy(pdoc, this.user)) throw new PermissionError(PERM.PERM_VIEW_PROBLEM_HIDDEN); if (!canViewCode) { rdoc.code = ''; rdoc.files = {}; diff --git a/packages/hydrooj/src/handler/training.ts b/packages/hydrooj/src/handler/training.ts index 9ddc92f3b..a334c1a61 100644 --- a/packages/hydrooj/src/handler/training.ts +++ b/packages/hydrooj/src/handler/training.ts @@ -9,6 +9,7 @@ import problem from '../model/problem'; import * as system from '../model/system'; import * as training from '../model/training'; import user from '../model/user'; +import { DomainModel } from '../plugin-api'; import * as bus from '../service/bus'; import { Handler, param, Types } from '../service/server'; @@ -97,7 +98,7 @@ class TrainingDetailHandler extends Handler { const tdoc = await training.get(domainId, tid); await bus.parallel('training/get', tdoc, this); let targetUser = this.user._id; - let enrollUsers = []; + let enrollUsers: number[] = []; let shouldCompare = false; const pids = training.getPids(tdoc.dag); if (this.user.hasPriv(PRIV.PRIV_USER_PROFILE)) { @@ -109,21 +110,24 @@ class TrainingDetailHandler extends Handler { } } const canViewHidden = this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN) || this.user._id; - const [udict, pdict] = await Promise.all([ - user.getList(domainId, [tdoc.owner, ...enrollUsers]), + const [udoc, udocs, dudocs, pdict, psdict, selfPsdict] = await Promise.all([ + user.getById(domainId, tdoc.owner), + user.getMulti({ _id: { $in: enrollUsers } }).project({ _id: 1, uname: 1, avatar: 1 }).toArray(), + DomainModel.getDomainUserMulti(domainId, enrollUsers).project({ uid: 1, displayName: 1 }).toArray(), problem.getList(domainId, pids, canViewHidden, true), + problem.getListStatus(domainId, targetUser, pids), + shouldCompare ? problem.getListStatus(domainId, this.user._id, pids) : {}, ]); - const psdict = await problem.getListStatus(domainId, targetUser, pids); - const selfPsdict = shouldCompare ? await problem.getListStatus(domainId, this.user._id, pids) : {}; + const dudict = {}; + for (const dudoc of dudocs) dudict[dudoc.uid] = dudoc.displayName; const donePids = new Set(); const progPids = new Set(); for (const pid in psdict) { if (!+pid) continue; const psdoc = psdict[pid]; if (psdoc.status) { - if (psdoc.status === builtin.STATUS.STATUS_ACCEPTED) { - donePids.add(parseInt(pid, 10)); - } else progPids.add(parseInt(pid, 10)); + if (psdoc.status === builtin.STATUS.STATUS_ACCEPTED) donePids.add(+pid); + else progPids.add(+pid); } } const nsdict = {}; @@ -149,7 +153,7 @@ class TrainingDetailHandler extends Handler { done: doneNids.size === tdoc.dag.length, }); this.response.body = { - tdoc, tsdoc, pids, pdict, psdict, ndict, nsdict, udict, enrollUsers, selfPsdict, + tdoc, tsdoc, pids, pdict, psdict, ndict, nsdict, udoc, udocs, dudict, selfPsdict, }; if (pjax) { const html = await this.renderHTML('partials/training_detail.html', this.response.body); diff --git a/packages/hydrooj/src/model/domain.ts b/packages/hydrooj/src/model/domain.ts index 7aa830ff0..389e07141 100644 --- a/packages/hydrooj/src/model/domain.ts +++ b/packages/hydrooj/src/model/domain.ts @@ -189,6 +189,10 @@ class DomainModel { return dudoc; } + static getDomainUserMulti(domainId: string, uids: number[]) { + return collUser.find({ domainId, uid: { $in: uids } }); + } + static setMultiUserInDomain(domainId: string, query: any, params: any) { deleteUserCache(domainId); return collUser.updateMany({ domainId, ...query }, { $set: params }, { upsert: true }); diff --git a/packages/hydrooj/src/service/storage.ts b/packages/hydrooj/src/service/storage.ts index 076ba731f..a9111ee67 100644 --- a/packages/hydrooj/src/service/storage.ts +++ b/packages/hydrooj/src/service/storage.ts @@ -10,7 +10,7 @@ import { createPresignedPost } from '@aws-sdk/s3-presigned-post'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; import { copyFile, createReadStream, createWriteStream, ensureDir, - remove, stat, writeFile, + existsSync, remove, stat, writeFile, } from 'fs-extra'; import { lookup } from 'mime-types'; import { Logger } from '../logger'; @@ -273,6 +273,7 @@ class LocalStorageService { async get(target: string, path?: string) { if (target.includes('..') || target.includes('//')) throw new Error('Invalid path'); target = resolve(this.dir, target); + if (!existsSync(target)) throw new Error('File not found'); if (path) await copyFile(target, path); return createReadStream(target); } diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 543927a2e..53437ea5f 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.42.19", + "version": "4.42.20", "author": "undefined ", "license": "AGPL-3.0", "main": "index.ts", diff --git a/packages/ui-default/templates/training_detail.html b/packages/ui-default/templates/training_detail.html index 825e2ff0c..455cde714 100644 --- a/packages/ui-default/templates/training_detail.html +++ b/packages/ui-default/templates/training_detail.html @@ -1,7 +1,7 @@ {% extends "layout/basic.html" %} {% block content %}