mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
upgrade to cordis v3 (#733)
Co-authored-by: panda <panda_dtdyy@outlook.com>
This commit is contained in:
1 parent
498cd57016
commit
a56b1650be
33 files changed
+301
-262
No files matched your search
@@ -14,7 +14,7 @@ export class CheckService extends Service {
|
||||
c = {};
|
||||
addChecker(type: string, checkFunc: CheckItem) {
|
||||
this.checkers[`check${type}`] = checkFunc;
|
||||
this.caller?.on('dispose', () => {
|
||||
this[Context.current]?.on('dispose', () => {
|
||||
delete this.checkers[`check${type}`];
|
||||
});
|
||||
}
|
||||
@@ -73,6 +73,6 @@ check.addChecker('Setting', async (ctx, log, warn) => {
|
||||
});
|
||||
|
||||
export async function apply(ctx: Context) {
|
||||
Context.service('check', CheckService);
|
||||
ctx.provide('check', CheckService, true);
|
||||
ctx.check = check;
|
||||
}
|
||||
@@ -479,12 +479,12 @@ class NotFoundHandler extends Handler {
|
||||
}
|
||||
|
||||
export class RouteService extends Service {
|
||||
static readonly methods = ['Route', 'Connection', 'withHandlerClass'];
|
||||
private registry = {};
|
||||
private registrationCount = Counter();
|
||||
|
||||
constructor(ctx) {
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'server', true);
|
||||
ctx.mixin('server', ['Route', 'Connection', 'withHandlerClass']);
|
||||
}
|
||||
|
||||
private register(func: typeof Route | typeof Connection, ...args: Parameters<typeof Route>) {
|
||||
@@ -498,7 +498,7 @@ export class RouteService extends Service {
|
||||
this.registrationCount[name]++;
|
||||
const res = func(...args);
|
||||
this.ctx.parallel(`handler/register/${name}`, HandlerClass);
|
||||
this.caller?.on('dispose', () => {
|
||||
this[Context.current]?.on('dispose', () => {
|
||||
this.registrationCount[name]--;
|
||||
if (!this.registrationCount[name]) delete this.registry[name];
|
||||
res();
|
||||
@@ -508,7 +508,7 @@ export class RouteService extends Service {
|
||||
public withHandlerClass(name: string, callback: (HandlerClass: typeof HandlerCommon) => any) {
|
||||
if (this.registry[name]) callback(this.registry[name]);
|
||||
this.ctx.on(`handler/register/${name}`, callback);
|
||||
this.caller?.on('dispose', () => {
|
||||
this[Context.current]?.on('dispose', () => {
|
||||
this.ctx.off(`handler/register/${name}`, callback);
|
||||
});
|
||||
}
|
||||
@@ -531,7 +531,7 @@ declare module '../context' {
|
||||
}
|
||||
|
||||
export async function apply(pluginContext: Context) {
|
||||
Context.service('server', RouteService);
|
||||
pluginContext.provide('server', undefined, true);
|
||||
pluginContext.server = new RouteService(pluginContext);
|
||||
app.keys = system.get('session.keys') as unknown as string[];
|
||||
if (process.env.HYDRO_CLI) return;
|
||||
|
||||
@@ -38,10 +38,9 @@ export default class Watcher extends Service {
|
||||
private declined: Set<string>;
|
||||
private stashed = new Set<string>();
|
||||
|
||||
constructor(public ctx: Context, private config: any) {
|
||||
constructor(public ctx: Context) {
|
||||
super(ctx, 'watcher', true);
|
||||
this.externals = new Set(Object.keys(require.cache));
|
||||
Context.service('watcher');
|
||||
}
|
||||
|
||||
start() {
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import moment from 'moment-timezone';
|
||||
import { sleep } from '@hydrooj/utils';
|
||||
import { Context, Service } from '../context';
|
||||
import db from './db';
|
||||
|
||||
declare module '../context' {
|
||||
interface Context {
|
||||
worker: WorkerService;
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkerService extends Service {
|
||||
private handlers: Record<string, Function> = {};
|
||||
consuming = true;
|
||||
running = null;
|
||||
promise: Promise<any> = null;
|
||||
coll = db.collection('schedule');
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'worker', true);
|
||||
this.consume();
|
||||
}
|
||||
|
||||
async getFirst() {
|
||||
if (process.env.CI) return null;
|
||||
const q = {
|
||||
executeAfter: { $lt: new Date() },
|
||||
type: 'schedule',
|
||||
subType: { $in: Object.keys(this.handlers) },
|
||||
};
|
||||
const res = await this.coll.findOneAndDelete(q);
|
||||
if (res.value) {
|
||||
this.ctx.logger.debug('%o', res.value);
|
||||
if (res.value.interval) {
|
||||
const executeAfter = moment(res.value.executeAfter).add(...res.value.interval).toDate();
|
||||
await this.coll.insertOne({ ...res.value, executeAfter });
|
||||
}
|
||||
return res.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async consume() {
|
||||
while (this.consuming) {
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const doc = await this.getFirst();
|
||||
if (!doc) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await sleep(1000);
|
||||
continue;
|
||||
}
|
||||
this.running = doc;
|
||||
this.ctx.logger.debug('Worker task: %o', doc);
|
||||
const start = Date.now();
|
||||
this.promise = Promise.race([
|
||||
this.handlers[doc.subType](doc).catch((e) => {
|
||||
this.ctx.logger.error('Worker task fail: ', e);
|
||||
this.ctx.logger.error('%o', doc);
|
||||
}),
|
||||
sleep(1200000),
|
||||
]);
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await this.promise;
|
||||
const spent = Date.now() - start;
|
||||
if (spent > 500) this.ctx.logger.warn('Slow worker task (%d ms): %o', spent, doc);
|
||||
this.running = null;
|
||||
} catch (err) {
|
||||
this.ctx.logger.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public addHandler(type: string, handler: Function) {
|
||||
this.handlers[type] = handler;
|
||||
this[Context.current]?.on('dispose', () => {
|
||||
delete this.handlers[type];
|
||||
});
|
||||
}
|
||||
|
||||
public async stop() {
|
||||
this.consuming = false;
|
||||
await this.promise;
|
||||
}
|
||||
}
|
||||
|
||||
export async function apply(ctx: Context) {
|
||||
ctx.provide('worker', undefined, true);
|
||||
ctx.worker = new WorkerService(ctx);
|
||||
}
|
||||
Reference in new issue
Block a user