mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: better discussion sort method
This commit is contained in:
1 parent
2232cf9ff5
commit
e7156a7c22
7 files changed
+52
-10
No files matched your search
@@ -39,6 +39,7 @@ rules:
|
|||||||
max-len:
|
max-len:
|
||||||
- warn
|
- warn
|
||||||
- 150
|
- 150
|
||||||
|
newline-per-chained-call: 0
|
||||||
no-bitwise: 0
|
no-bitwise: 0
|
||||||
no-console: 0
|
no-console: 0
|
||||||
no-continue: 0
|
no-continue: 0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydrooj",
|
"name": "hydrooj",
|
||||||
"version": "2.26.10",
|
"version": "2.26.11",
|
||||||
"bin": "bin/hydrooj.js",
|
"bin": "bin/hydrooj.js",
|
||||||
"main": "dist/loader.js",
|
"main": "dist/loader.js",
|
||||||
"typings": "dist/loader.d.ts",
|
"typings": "dist/loader.d.ts",
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class DiscussionCreateHandler extends DiscussionHandler {
|
|||||||
await this.limitRate('add_discussion', 3600, 60);
|
await this.limitRate('add_discussion', 3600, 60);
|
||||||
let name: ObjectID | string | number;
|
let name: ObjectID | string | number;
|
||||||
if (ObjectID.isValid(_name)) name = new ObjectID(_name);
|
if (ObjectID.isValid(_name)) name = new ObjectID(_name);
|
||||||
else if (isSafeInteger(parseInt(_name, 10))) name = parseInt(_name, 10);
|
else if (isSafeInteger(+name)) name = +name;
|
||||||
else name = _name;
|
else name = _name;
|
||||||
if (highlight) this.checkPerm(PERM.PERM_HIGHLIGHT_DISCUSSION);
|
if (highlight) this.checkPerm(PERM.PERM_HIGHLIGHT_DISCUSSION);
|
||||||
if (pin) this.checkPerm(PERM.PERM_PIN_DISCUSSION);
|
if (pin) this.checkPerm(PERM.PERM_PIN_DISCUSSION);
|
||||||
|
|||||||
@@ -360,6 +360,8 @@ declare module './model/discussion' {
|
|||||||
nReply: number,
|
nReply: number,
|
||||||
views: number,
|
views: number,
|
||||||
history: HistoryDoc[],
|
history: HistoryDoc[],
|
||||||
|
sort: number,
|
||||||
|
lastRCount: number,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { FilterQuery, ObjectID } from 'mongodb';
|
import { FilterQuery, ObjectID } from 'mongodb';
|
||||||
import { omit } from 'lodash';
|
import { omit } from 'lodash';
|
||||||
|
import moment from 'moment';
|
||||||
import problem from './problem';
|
import problem from './problem';
|
||||||
import * as contest from './contest';
|
import * as contest from './contest';
|
||||||
import * as training from './training';
|
import * as training from './training';
|
||||||
import * as document from './document';
|
import * as document from './document';
|
||||||
|
import TaskModel from './task';
|
||||||
import { DiscussionNodeNotFoundError, DocumentNotFoundError } from '../error';
|
import { DiscussionNodeNotFoundError, DocumentNotFoundError } from '../error';
|
||||||
import { DiscussionReplyDoc, DiscussionTailReplyDoc, Document } from '../interface';
|
import { DiscussionReplyDoc, DiscussionTailReplyDoc, Document } from '../interface';
|
||||||
import { buildProjection } from '../utils';
|
import { buildProjection } from '../utils';
|
||||||
@@ -82,6 +84,7 @@ export async function add(
|
|||||||
pin,
|
pin,
|
||||||
updateAt: new Date(),
|
updateAt: new Date(),
|
||||||
views: 0,
|
views: 0,
|
||||||
|
sort: 100,
|
||||||
};
|
};
|
||||||
await bus.serial('discussion/before-add', payload);
|
await bus.serial('discussion/before-add', payload);
|
||||||
const res = await document.add(
|
const res = await document.add(
|
||||||
@@ -125,7 +128,7 @@ export function count(domainId: string, query: FilterQuery<DiscussionDoc>) {
|
|||||||
|
|
||||||
export function getMulti(domainId: string, query: FilterQuery<DiscussionDoc> = {}, projection = PROJECTION_LIST) {
|
export function getMulti(domainId: string, query: FilterQuery<DiscussionDoc> = {}, projection = PROJECTION_LIST) {
|
||||||
return document.getMulti(domainId, document.TYPE_DISCUSSION, query)
|
return document.getMulti(domainId, document.TYPE_DISCUSSION, query)
|
||||||
.sort({ pin: -1, updateAt: -1 })
|
.sort({ pin: -1, sort: -1 })
|
||||||
.project(buildProjection(projection));
|
.project(buildProjection(projection));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,6 +280,33 @@ bus.on('problem/delete', async (domainId, docId) => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const t = Math.exp(-0.15);
|
||||||
|
|
||||||
|
async function updateSort() {
|
||||||
|
const cursor = document.coll.find({ docType: document.TYPE_DISCUSSION });
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const data = await cursor.next();
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const rCount = await getMultiReply(data.domainId, data.docId).count();
|
||||||
|
const sort = ((data.sort || 100) + Math.max(rCount - (data.lastRCount || 0), 0) * 10) * t;
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
await document.coll.updateOne({ _id: data._id }, { $set: { sort, lastRCount: rCount } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TaskModel.Worker.addHandler('discussion.sort', updateSort);
|
||||||
|
|
||||||
|
bus.once('app/started', async () => {
|
||||||
|
if (!await TaskModel.count({ type: 'schedule', subType: 'discussion.sort' })) {
|
||||||
|
await TaskModel.add({
|
||||||
|
type: 'schedule',
|
||||||
|
subType: 'discussion.sort',
|
||||||
|
executeAfter: moment().minute(0).second(0).millisecond(0).toDate(),
|
||||||
|
interval: [1, 'hour'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
global.Hydro.model.discussion = {
|
global.Hydro.model.discussion = {
|
||||||
typeDisplay,
|
typeDisplay,
|
||||||
DiscussionDoc,
|
DiscussionDoc,
|
||||||
|
|||||||
@@ -25,14 +25,10 @@ async function getFirst(query: FilterQuery<Task>) {
|
|||||||
class Consumer {
|
class Consumer {
|
||||||
consuming: boolean;
|
consuming: boolean;
|
||||||
running?: any;
|
running?: any;
|
||||||
filter: any;
|
|
||||||
func: Function;
|
|
||||||
timeout: NodeJS.Timeout;
|
timeout: NodeJS.Timeout;
|
||||||
|
|
||||||
constructor(filter: any, func: Function) {
|
constructor(public filter: any, public func: Function, public destoryOnError = true) {
|
||||||
this.consuming = true;
|
this.consuming = true;
|
||||||
this.filter = filter;
|
|
||||||
this.func = func;
|
|
||||||
this.get = this.get.bind(this);
|
this.get = this.get.bind(this);
|
||||||
this.get();
|
this.get();
|
||||||
}
|
}
|
||||||
@@ -48,7 +44,7 @@ class Consumer {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
this.destory();
|
if (this.destoryOnError) this.destory();
|
||||||
}
|
}
|
||||||
this.timeout = setTimeout(this.get, 100);
|
this.timeout = setTimeout(this.get, 100);
|
||||||
}
|
}
|
||||||
@@ -71,6 +67,7 @@ class WorkerService implements BaseService {
|
|||||||
logger.debug('Worker task: %o', doc);
|
logger.debug('Worker task: %o', doc);
|
||||||
return this.handlers[doc.subType](doc);
|
return this.handlers[doc.subType](doc);
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
this.started = true;
|
this.started = true;
|
||||||
}
|
}
|
||||||
@@ -113,7 +110,7 @@ class TaskModel {
|
|||||||
|
|
||||||
static async getDelay(query?: FilterQuery<Task>) {
|
static async getDelay(query?: FilterQuery<Task>) {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const [res] = await coll.find(query).sort({ executeAfter: 1 }).limit(1).toArray();
|
const res = await coll.findOne(query, { sort: { executeAfter: 1 } });
|
||||||
if (res) return [Math.max(0, now.getTime() - res.executeAfter.getTime()), res.executeAfter];
|
if (res) return [Math.max(0, now.getTime() - res.executeAfter.getTime()), res.executeAfter];
|
||||||
return [0, now];
|
return [0, now];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import db from './service/db';
|
|||||||
import difficultyAlgorithm from './lib/difficulty';
|
import difficultyAlgorithm from './lib/difficulty';
|
||||||
import problem from './model/problem';
|
import problem from './model/problem';
|
||||||
import user from './model/user';
|
import user from './model/user';
|
||||||
|
import * as discussion from './model/discussion';
|
||||||
import domain from './model/domain';
|
import domain from './model/domain';
|
||||||
import * as document from './model/document';
|
import * as document from './model/document';
|
||||||
import * as system from './model/system';
|
import * as system from './model/system';
|
||||||
@@ -352,6 +353,17 @@ const scripts: UpgradeScript[] = [
|
|||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
async function _27_28() {
|
||||||
|
const cursor = document.coll.find({ docType: document.TYPE_DISCUSSION });
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
const data = await cursor.next();
|
||||||
|
const t = Math.exp(-0.15 * (((new Date().getTime() / 1000) - data._id.generationTime) / 3600));
|
||||||
|
const rCount = await discussion.getMultiReply(data.domainId, data.docId).count();
|
||||||
|
const sort = ((data.sort || 100) + Math.max(rCount - (data.lastRCount || 0), 0) * 10) * t;
|
||||||
|
await document.coll.updateOne({ _id: data._id }, { $set: { sort, lastRCount: rCount } });
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default scripts;
|
export default scripts;
|
||||||
Reference in new issue
Block a user