upgrade to cordis v3 (#733)

Co-authored-by: panda <panda_dtdyy@outlook.com>
This commit is contained in:
undefinedandpanda authored and GitHub committed 2024-03-07 01:32:58 +08:00
1 parent 498cd57016
commit a56b1650be
33 files changed
+301 -262

No files matched your search

+2 -2
View File
@@ -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;
}
+5 -5
View File
@@ -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;
+1 -2
View File
@@ -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() {
+90
View File
@@ -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);
}