自动释放锁,优化record.getList()

This commit is contained in:
undefined committed 2020-07-27 17:45:32 +08:00
1 parent d3deeaeb96
commit 2bf6adbaa0
12 files changed
+46 -23

No files matched your search

+4
View File
@@ -3,6 +3,7 @@
import os from 'os'; import os from 'os';
import path from 'path'; import path from 'path';
import fs from 'fs-extra'; import fs from 'fs-extra';
import pslist from 'ps-list';
import { argv } from 'yargs'; import { argv } from 'yargs';
import { builtinModel } from './common'; import { builtinModel } from './common';
import { Entry } from '../loader'; import { Entry } from '../loader';
@@ -13,9 +14,12 @@ const lockfile = path.resolve(tmpdir, 'lock.json');
export async function load(call: Entry) { export async function load(call: Entry) {
if (fs.existsSync(lockfile) && !argv.ignorelock) { if (fs.existsSync(lockfile) && !argv.ignorelock) {
const file = require(lockfile); const file = require(lockfile);
const plist = await pslist();
if (file.pid && plist.map((i) => i.pid).includes(file.pid)) {
console.error(`Lockfile exists, pid=${file.pid}`); console.error(`Lockfile exists, pid=${file.pid}`);
process.exit(1); process.exit(1);
} }
}
const context = { const context = {
addons: global.addons, addons: global.addons,
pid: process.pid, pid: process.pid,
+1 -1
View File
@@ -73,7 +73,7 @@ class ContestDetailHandler extends ContestHandler {
if (this.canShowRecord(tdoc)) { if (this.canShowRecord(tdoc)) {
const q = []; const q = [];
for (const i in psdict) q.push(psdict[i].rid); for (const i in psdict) q.push(psdict[i].rid);
rdict = await record.getList(domainId, q); rdict = await record.getList(domainId, q, true);
} else { } else {
for (const i in psdict) rdict[psdict[i].rid] = { _id: psdict[i].rid }; for (const i in psdict) rdict[psdict[i].rid] = { _id: psdict[i].rid };
} }
+12
View File
@@ -1,9 +1,11 @@
import { ObjectID } from 'mongodb'; import { ObjectID } from 'mongodb';
import { isSafeInteger } from 'lodash'; import { isSafeInteger } from 'lodash';
import { DiscussionNotFoundError, DocumentNotFoundError } from '../error'; import { DiscussionNotFoundError, DocumentNotFoundError } from '../error';
import { Drdoc, Mdoc } from '../interface';
import paginate from '../lib/paginate'; import paginate from '../lib/paginate';
import * as system from '../model/system'; import * as system from '../model/system';
import * as user from '../model/user'; import * as user from '../model/user';
import * as message from '../model/message';
import * as discussion from '../model/discussion'; import * as discussion from '../model/discussion';
import * as document from '../model/document'; import * as document from '../model/document';
import { PERM, PRIV } from '../model/builtin'; import { PERM, PRIV } from '../model/builtin';
@@ -213,6 +215,16 @@ class DiscussionDetailHandler extends DiscussionHandler {
async postReply(domainId: string, did: ObjectID, content: string) { async postReply(domainId: string, did: ObjectID, content: string) {
this.checkPerm(PERM.PERM_REPLY_DISCUSSION); this.checkPerm(PERM.PERM_REPLY_DISCUSSION);
this.limitRate('add_discussion', 3600, 30); this.limitRate('add_discussion', 3600, 30);
// Notify related users
const replies: Drdoc[] = await discussion.getMultiReply(domainId, did).toArray();
const uids = Array.from(new Set(replies.map((drdoc) => drdoc.owner)));
const tasks = uids.map((uid) => {
if (uid !== this.user._id) {
return message.send(1, uid, `Discussion update: ${domainId} ${did}`);
}
return Promise.resolve(null as Mdoc);
});
await Promise.all(tasks);
await discussion.addReply(domainId, did, this.user._id, content, this.request.ip); await discussion.addReply(domainId, did, this.user._id, content, this.request.ip);
this.back(); this.back();
} }
+1 -5
View File
@@ -24,11 +24,7 @@ import {
Route, Connection, Handler, ConnectionHandler, Types, param, multipart, Route, Connection, Handler, ConnectionHandler, Types, param, multipart,
} from '../service/server'; } from '../service/server';
const parseCategory = (value: string) => { const parseCategory = (value: string) => flatten(value.split('+').map((e) => e.split(','))).map((e) => e.trim());
if (!value) return [];
console.log(value);
return flatten(value.split('+').map((e) => e.split(','))).map((e) => e.trim());
};
const parsePid = (value: string) => (isSafeInteger(value) ? parseInt(value, 10) : value); const parsePid = (value: string) => (isSafeInteger(value) ? parseInt(value, 10) : value);
class ProblemHandler extends Handler { class ProblemHandler extends Handler {
+5 -3
View File
@@ -28,7 +28,7 @@ export function* paginate(page: number, numPages: number) {
let first: number; let first: number;
let last: number; let last: number;
if (page > 1) { if (page > 1) {
yield ['first', 1]; if (page > 2) yield ['first', 1];
yield ['previous', page - 1]; yield ['previous', page - 1];
} }
if (page <= radius) [first, last] = [1, Math.min(1 + radius * 2, numPages)]; if (page <= radius) [first, last] = [1, Math.min(1 + radius * 2, numPages)];
@@ -43,8 +43,10 @@ export function* paginate(page: number, numPages: number) {
else yield ['current', page]; else yield ['current', page];
} }
if (last < numPages) yield ['ellipsis', 0]; if (last < numPages) yield ['ellipsis', 0];
if (page < numPages) yield ['next', page + 1]; if (page < numPages) {
yield ['last', numPages]; yield ['next', page + 1];
if (page < numPages - 1) yield ['last', numPages];
}
} }
export function size(s: number, base = 1) { export function size(s: number, base = 1) {
+1 -1
View File
@@ -18,7 +18,7 @@ class Loader extends nunjucks.Loader {
}; };
} }
let fullpath = null; let fullpath = null;
const p = path.resolve(argv.template as string, name); const p = path.resolve(process.cwd(), argv.template as string, name);
if (fs.existsSync(p)) fullpath = p; if (fs.existsSync(p)) fullpath = p;
if (!fullpath) throw new Error(`Cannot get template ${name}`); if (!fullpath) throw new Error(`Cannot get template ${name}`);
return { return {
+1 -1
View File
@@ -133,7 +133,7 @@ const publicTemp = path.resolve(os.tmpdir(), 'hydro', 'public');
const tmp = path.resolve(os.tmpdir(), 'hydro', '__'); const tmp = path.resolve(os.tmpdir(), 'hydro', '__');
export function addon(addonPath: string) { export function addon(addonPath: string) {
let modulePath = path.resolve(addonPath); let modulePath = path.resolve(process.cwd(), addonPath);
if (!(fs.existsSync(addonPath) && fs.statSync(addonPath).isFile())) { if (!(fs.existsSync(addonPath) && fs.statSync(addonPath).isFile())) {
try { try {
// Is a npm package // Is a npm package
+2 -3
View File
@@ -200,11 +200,10 @@ export function getNodes(domainId: string) {
export async function getListVnodes(domainId: string, ddocs: any, handler: any) { export async function getListVnodes(domainId: string, ddocs: any, handler: any) {
const tasks = []; const tasks = [];
const res = {}; const res = {};
function task(ddoc) { async function task(ddoc) {
return getVnode(domainId, ddoc, handler).then((vnode) => { const vnode = await getVnode(domainId, ddoc, handler);
if (!res[ddoc.parentType]) res[ddoc.parentType] = {}; if (!res[ddoc.parentType]) res[ddoc.parentType] = {};
res[ddoc.parentType][ddoc.parentId] = vnode; res[ddoc.parentType][ddoc.parentId] = vnode;
});
} }
for (const ddoc of ddocs) tasks.push(task(ddoc)); for (const ddoc of ddocs) tasks.push(task(ddoc));
await Promise.all(tasks); await Promise.all(tasks);
+6 -6
View File
@@ -140,14 +140,14 @@ export function count(domainId: string, query: any) {
} }
export async function getList( export async function getList(
domainId: string, rids: ObjectID[], showHidden = false, domainId: string, rids: ObjectID[], showHidden: boolean,
): Promise<Dictionary<Rdoc>> { ): Promise<Dictionary<Rdoc>> {
const r = {}; const r = {};
for (const rid of rids) { rids = Array.from(new Set(rids));
// eslint-disable-next-line no-await-in-loop const rdocs = await coll.find({ domainId, _id: { $in: rids } }).toArray();
const rdoc = await get(domainId, rid); for (const rdoc of rdocs) {
if (rdoc.hidden && !showHidden) r[rid.toHexString()] = null; if (rdoc.hidden && !showHidden) r[rdoc._id.toHexString()] = null;
else r[rid.toHexString()] = rdoc; else r[rdoc._id.toHexString()] = rdoc;
} }
return r; return r;
} }
+6 -2
View File
@@ -391,8 +391,12 @@ export class Handler {
this.response.status = error instanceof UserFacingError ? error.code : 500; this.response.status = error instanceof UserFacingError ? error.code : 500;
if (this.request.json) this.response.body = { error }; if (this.request.json) this.response.body = { error };
else { else {
await this.render(error instanceof UserFacingError ? 'error.html' : 'bsod.html', { error }) try {
.catch(() => { }); await this.render(error instanceof UserFacingError ? 'error.html' : 'bsod.html', { error });
} catch (e) {
console.error(e);
// this.response.body.error = {};
}
} }
} }
await this.putResponse(); await this.putResponse();
+2 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "hydrooj", "name": "hydrooj",
"version": "2.10.9", "version": "2.10.10",
"main": "dist/loader.js", "main": "dist/loader.js",
"bin": "bin/hydrooj.js", "bin": "bin/hydrooj.js",
"repository": "https://github.com/hydro-dev/Hydro.git", "repository": "https://github.com/hydro-dev/Hydro.git",
@@ -33,6 +33,7 @@
"nodemailer": "^6.4.10", "nodemailer": "^6.4.10",
"nunjucks": "^3.2.2", "nunjucks": "^3.2.2",
"prismjs": "^1.20.0", "prismjs": "^1.20.0",
"ps-list": "^7.2.0",
"serialize-javascript": "^4.0.0", "serialize-javascript": "^4.0.0",
"sockjs": "^0.3.20", "sockjs": "^0.3.20",
"superagent": "^5.2.2", "superagent": "^5.2.2",
+5
View File
@@ -2270,6 +2270,11 @@ proxy-from-env@^1.0.0:
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
ps-list@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-7.2.0.tgz#3d110e1de8249a4b178c9b1cf2a215d1e4e42fc0"
integrity sha512-v4Bl6I3f2kJfr5o80ShABNHAokIgY+wFDTQfE+X3zWYgSGQOCBeYptLZUpoOALBqO5EawmDN/tjTldJesd0ujQ==
punycode@^2.1.0: punycode@^2.1.0:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"