From 033e88fdce6594b2c20edc4776637329a7841dc6 Mon Sep 17 00:00:00 2001 From: undefined Date: Fri, 21 Mar 2025 07:46:36 +0800 Subject: [PATCH] core: cordis alpha.7 --- framework/framework/server.ts | 22 +++++++++++++++++----- packages/elastic/index.ts | 2 +- packages/hydrooj/package.json | 6 +++--- packages/hydrooj/src/entry/cli.ts | 2 +- packages/hydrooj/src/entry/worker.ts | 6 +++++- packages/hydrooj/src/model/schedule.ts | 2 +- packages/hydrooj/src/model/setting.ts | 1 - packages/hydrooj/src/service/db.ts | 8 ++------ packages/hydrooj/src/service/worker.ts | 7 +------ packages/hydrooj/src/settings.ts | 2 +- packages/ui-default/backendlib/template.ts | 2 +- packages/ui-default/package.json | 8 ++++---- packages/ui-next/package.json | 4 ++-- packages/vjudge/src/index.ts | 2 +- 14 files changed, 40 insertions(+), 34 deletions(-) diff --git a/framework/framework/server.ts b/framework/framework/server.ts index 5e2d049ca..7a4a630be 100644 --- a/framework/framework/server.ts +++ b/framework/framework/server.ts @@ -41,6 +41,16 @@ export function encodeRFC5987ValueChars(str: string) { ); } +async function forkContextWithScope(ctx: C) { + const scope = ctx.plugin(() => { }); + await scope; + return { + scope, + ctx: scope.ctx, + [Symbol.asyncDispose]: () => scope.dispose(), + }; +} + export interface HydroRequest { method: string; host: string; @@ -144,7 +154,6 @@ export class HandlerCommon { this.request = context.HydroContext.request; this.response = context.HydroContext.response; this.UiContext = context.HydroContext.UiContext; - this.ctx = (ctx as any).extend({}); } checkPerm(..._: bigint[]) { @@ -472,10 +481,11 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`); }); } - private async handleHttp(ctx: KoaContext, HandlerClass, checker, savedContext) { + private async handleHttp(ctx: KoaContext, HandlerClass, checker, savedContext: C) { const { args } = ctx.HydroContext; Object.assign(args, ctx.params); - const h = new HandlerClass(ctx, savedContext); + await using sub = await forkContextWithScope(savedContext); + const h = new HandlerClass(ctx, sub.ctx); ctx.handler = h; const method = ctx.method.toLowerCase(); const name = ((Object.hasOwn(HandlerClass, kHandler) && typeof HandlerClass[kHandler] === 'string') @@ -553,7 +563,8 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`); private async handleWS(ctx: KoaContext, HandlerClass, checker, conn?, layer?, savedContext?) { const { args } = ctx.HydroContext; - const h = new HandlerClass(ctx, savedContext); + const sub = await forkContextWithScope(savedContext); + const h = new HandlerClass(ctx, sub.ctx); // FIXME: should pass type check await (this.ctx.parallel as any)('connection/create', h); const stream = new PassThrough(); @@ -596,7 +607,8 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`); if (layer) layer.clients.delete(conn); if (err && !layer) ctx.status = 500; if (interval) clearInterval(interval); - h.cleanup?.(args); + await h.cleanup?.(args); + await sub.scope.dispose(); }; try { diff --git a/packages/elastic/index.ts b/packages/elastic/index.ts index 5c3f64f9d..331d5612b 100644 --- a/packages/elastic/index.ts +++ b/packages/elastic/index.ts @@ -92,7 +92,7 @@ export default class ElasticSearchService extends Service { return true; } - async [Service.setup]() { + async [Context.init]() { await this.client.nodes.stats(); this.ctx.on('problem/add', async (doc, docId) => { await this.client.index({ diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index e53b0c190..0fa8b2f3c 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -16,8 +16,8 @@ "@aws-sdk/lib-storage": "3.726.1", "@aws-sdk/s3-presigned-post": "3.726.1", "@aws-sdk/s3-request-presigner": "3.726.1", - "@cordisjs/core": "4.0.0-alpha.6", - "@cordisjs/logger": "1.0.0-alpha.3", + "@cordisjs/core": "4.0.0-alpha.7", + "@cordisjs/logger": "1.0.0-alpha.4", "@cordisjs/plugin-timer": "1.0.0-alpha.0", "@graphql-tools/schema": "^10.0.23", "@hydrooj/common": "workspace:^", @@ -33,7 +33,7 @@ "emojis-list": "2.1.0", "fs-extra": "^11.3.0", "graphql": "^16.10.0", - "graphql-scalars": "^1.24.1", + "graphql-scalars": "^1.24.2", "js-yaml": "^4.1.0", "koa-proxies": "^0.12.4", "koa-static-cache": "^5.1.4", diff --git a/packages/hydrooj/src/entry/cli.ts b/packages/hydrooj/src/entry/cli.ts index ed605d181..70299d062 100644 --- a/packages/hydrooj/src/entry/cli.ts +++ b/packages/hydrooj/src/entry/cli.ts @@ -130,7 +130,7 @@ export async function load(ctx: Context) { await setting(pending, fail, require('../model/setting')); ctx.plugin(require('../service/server')); ctx = await new Promise((resolve) => { - ctx.inject(['server'], (c) => { + ctx.inject(['server', 'setting', 'worker'], (c) => { resolve(c); }); }); diff --git a/packages/hydrooj/src/entry/worker.ts b/packages/hydrooj/src/entry/worker.ts index fedb1c7d2..3a6d949cd 100644 --- a/packages/hydrooj/src/entry/worker.ts +++ b/packages/hydrooj/src/entry/worker.ts @@ -59,7 +59,11 @@ export async function apply(ctx: Context) { await builtinModel(ctx); await model(pending, fail, ctx); await setting(pending, fail, require('../model/setting')); - + ctx = await new Promise((resolve) => { + ctx.inject(['worker', 'setting'], (c) => { + resolve(c); + }); + }); const handlerDir = path.resolve(__dirname, '..', 'handler'); const handlers = await fs.readdir(handlerDir); for (const h of handlers.filter((i) => i.endsWith('.ts'))) { diff --git a/packages/hydrooj/src/model/schedule.ts b/packages/hydrooj/src/model/schedule.ts index 107ab09b0..ea2c73115 100644 --- a/packages/hydrooj/src/model/schedule.ts +++ b/packages/hydrooj/src/model/schedule.ts @@ -4,7 +4,7 @@ import { Context } from '../context'; import { Schedule } from '../interface'; import { Logger } from '../logger'; import db from '../service/db'; -import type { WorkerService } from '../service/worker'; +import type WorkerService from '../service/worker'; import RecordModel from './record'; const logger = new Logger('model/schedule'); diff --git a/packages/hydrooj/src/model/setting.ts b/packages/hydrooj/src/model/setting.ts index 22c778ddb..420d2718d 100644 --- a/packages/hydrooj/src/model/setting.ts +++ b/packages/hydrooj/src/model/setting.ts @@ -389,7 +389,6 @@ export class SettingService extends Service { export const inject = ['db']; export async function apply(ctx: Context) { - ctx.provide('setting', undefined, true); ctx.plugin(SettingService); logger.info('Ensuring settings'); const system = global.Hydro.model.system; diff --git a/packages/hydrooj/src/service/db.ts b/packages/hydrooj/src/service/db.ts index 51a2ea12f..9455f1e78 100644 --- a/packages/hydrooj/src/service/db.ts +++ b/packages/hydrooj/src/service/db.ts @@ -55,10 +55,11 @@ export class MongoService extends Service { return mongourl; } - async [Service.setup]() { + async *[Context.init]() { const mongourl = await MongoService.getUrl(); const url = mongoUri.parse(mongourl); this.client = await MongoClient.connect(mongourl); + yield () => { this.client.close(); } this.db = this.client.db(url.database || 'hydro'); await bus.parallel('database/connect', this.db); this.ctx.setInterval(() => this.fixExpireAfter(), Time.hour); @@ -176,11 +177,6 @@ export class MongoService extends Service { } return results; } - - public async apply(ctx) { - await this.start(); - ctx.on('dispose', () => this.client.close()); - } } /** @deprecated use ctx.db instead */ diff --git a/packages/hydrooj/src/service/worker.ts b/packages/hydrooj/src/service/worker.ts index 192e522b4..a6c7b078d 100644 --- a/packages/hydrooj/src/service/worker.ts +++ b/packages/hydrooj/src/service/worker.ts @@ -9,7 +9,7 @@ declare module '../context' { } } -export class WorkerService extends Service { +export default class WorkerService extends Service { private handlers: Record = {}; consuming = true; running = null; @@ -85,8 +85,3 @@ export class WorkerService extends Service { await this.promise; } } - -export async function apply(ctx: Context) { - ctx.provide('worker', undefined, true); - ctx.worker = new WorkerService(ctx); -} diff --git a/packages/hydrooj/src/settings.ts b/packages/hydrooj/src/settings.ts index bbba1751e..173990947 100644 --- a/packages/hydrooj/src/settings.ts +++ b/packages/hydrooj/src/settings.ts @@ -27,7 +27,7 @@ export class ConfigService extends Service { super(ctx, 'config'); } - async [Service.setup]() { + async [Context.init]() { const payload = await this.ctx.db.collection('system').find({}).toArray(); this.initialValues = Object.fromEntries(payload.map((v) => [v._id, v.value])); return await this.loadConfig(); diff --git a/packages/ui-default/backendlib/template.ts b/packages/ui-default/backendlib/template.ts index fd0f57850..473f43f52 100644 --- a/packages/ui-default/backendlib/template.ts +++ b/packages/ui-default/backendlib/template.ts @@ -251,7 +251,7 @@ export class TemplateService extends Service { }); } - async [Service.setup]() { + async [Context.init]() { const pending = Object.values(global.addons); const logger = this.ctx.logger('template'); for (const i of pending) { diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 0c92deb83..d2c22ed25 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -15,7 +15,7 @@ }, "devDependencies": { "@blueprintjs/core": "^5.17.6", - "@cordisjs/core": "4.0.0-alpha.6", + "@cordisjs/core": "4.0.0-alpha.7", "@fontsource/dm-mono": "^5.2.5", "@fontsource/fira-code": "^5.2.5", "@fontsource/inconsolata": "^5.2.5", @@ -25,7 +25,7 @@ "@fontsource/source-code-pro": "^5.2.5", "@fontsource/ubuntu-mono": "^5.2.5", "@hydrooj/utils": "workspace:^", - "@sentry/browser": "^9.6.0", + "@sentry/browser": "^9.7.0", "@sentry/webpack-plugin": "^3.2.2", "@simplewebauthn/browser": "13.1.0", "@svgr/webpack": "^8.1.0", @@ -38,7 +38,7 @@ "@types/nunjucks": "^3.2.6", "@types/pickadate": "^3.5.35", "@types/qrcode": "^1.5.5", - "@types/react": "^18.3.18", + "@types/react": "^18.3.19", "@types/react-dom": "^18.3.5", "@types/redux-logger": "^3.0.13", "@types/uuid": "^10.0.0", @@ -78,7 +78,7 @@ "monaco-editor-webpack-plugin": "^7.1.0", "monaco-themes": "^0.4.4", "monaco-yaml": "5.1.1", - "nanoid": "^5.1.4", + "nanoid": "^5.1.5", "normalize.css": "^8.0.1", "nprogress": "^0.2.0", "p-queue": "^8.1.0", diff --git a/packages/ui-next/package.json b/packages/ui-next/package.json index b341e485c..89ed6e819 100644 --- a/packages/ui-next/package.json +++ b/packages/ui-next/package.json @@ -14,9 +14,9 @@ }, "devDependencies": { "@eslint/js": "^9.22.0", - "@types/react": "^19.0.10", + "@types/react": "^19.0.12", "@types/react-dom": "^19.0.4", - "@vitejs/plugin-react-swc": "^3.8.0", + "@vitejs/plugin-react-swc": "^3.8.1", "typescript": "~5.8.2", "vite": "^6.2.2" } diff --git a/packages/vjudge/src/index.ts b/packages/vjudge/src/index.ts index 8e79a92a4..a852d302c 100644 --- a/packages/vjudge/src/index.ts +++ b/packages/vjudge/src/index.ts @@ -188,7 +188,7 @@ class VJudgeService extends Service { accounts: RemoteAccount[] = []; private providers: Record = {}; private pool: Record = {}; - async [Service.setup]() { + async [Context.init]() { if (process.env.NODE_APP_INSTANCE !== '0') return; if (process.env.HYDRO_CLI) return; this.accounts = await coll.find().toArray();