mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: bug fixes
This commit is contained in:
4 files changed
+37
-28
No files matched your search
@@ -550,7 +550,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleWS(ctx: KoaContext, HandlerClass, checker, conn, layer?) {
|
private async handleWS(ctx: KoaContext, HandlerClass, checker, conn?, layer?) {
|
||||||
const { args } = ctx.HydroContext;
|
const { args } = ctx.HydroContext;
|
||||||
const h = new HandlerClass(ctx, this.ctx);
|
const h = new HandlerClass(ctx, this.ctx);
|
||||||
// FIXME: should pass type check
|
// FIXME: should pass type check
|
||||||
@@ -581,6 +581,23 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
|||||||
ctx.handler = h;
|
ctx.handler = h;
|
||||||
h.conn = conn;
|
h.conn = conn;
|
||||||
const disposables = [];
|
const disposables = [];
|
||||||
|
let interval: NodeJS.Timeout;
|
||||||
|
let closed = false;
|
||||||
|
|
||||||
|
const clean = async (err?: Error) => {
|
||||||
|
if (closed) return;
|
||||||
|
closed = true;
|
||||||
|
if (err) await h.onerror(err);
|
||||||
|
// FIXME: should pass type check
|
||||||
|
else (this.ctx.emit as any)('connection/close', h);
|
||||||
|
h.active = false;
|
||||||
|
for (const d of disposables) d();
|
||||||
|
if (layer) layer.clients.delete(conn);
|
||||||
|
if (err && !layer) ctx.status = 500;
|
||||||
|
if (interval) clearInterval(interval);
|
||||||
|
h.cleanup?.(args);
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// FIXME: should pass type check
|
// FIXME: should pass type check
|
||||||
await (this.ctx.parallel as any)('handler/create', h, 'ws');
|
await (this.ctx.parallel as any)('handler/create', h, 'ws');
|
||||||
@@ -591,18 +608,6 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
|||||||
if (h.prepare) await h.prepare(args);
|
if (h.prepare) await h.prepare(args);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
for (const { name, target } of h.__subscribe || []) disposables.push(this.ctx.on(name, target.bind(h)));
|
for (const { name, target } of h.__subscribe || []) disposables.push(this.ctx.on(name, target.bind(h)));
|
||||||
let closed = false;
|
|
||||||
let interval: NodeJS.Timeout;
|
|
||||||
const clean = () => {
|
|
||||||
if (closed) return;
|
|
||||||
closed = true;
|
|
||||||
// FIXME: should pass type check
|
|
||||||
(this.ctx.emit as any)('connection/close', h);
|
|
||||||
if (layer) layer.clients.delete(conn);
|
|
||||||
if (interval) clearInterval(interval);
|
|
||||||
for (const d of disposables) d();
|
|
||||||
h.cleanup?.(args);
|
|
||||||
};
|
|
||||||
if (layer) {
|
if (layer) {
|
||||||
let lastHeartbeat = Date.now();
|
let lastHeartbeat = Date.now();
|
||||||
interval = setInterval(() => {
|
interval = setInterval(() => {
|
||||||
@@ -615,7 +620,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
|||||||
conn.on('pong', () => {
|
conn.on('pong', () => {
|
||||||
lastHeartbeat = Date.now();
|
lastHeartbeat = Date.now();
|
||||||
});
|
});
|
||||||
conn.onmessage = (e) => {
|
conn.onmessage = async (e) => {
|
||||||
lastHeartbeat = Date.now();
|
lastHeartbeat = Date.now();
|
||||||
if (e.data === 'pong') return;
|
if (e.data === 'pong') return;
|
||||||
if (e.data === 'ping') {
|
if (e.data === 'ping') {
|
||||||
@@ -629,7 +634,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
|||||||
conn.close();
|
conn.close();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
h.message?.(payload);
|
await h.message?.(payload);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
}
|
}
|
||||||
@@ -637,15 +642,20 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
|||||||
} else ctx.body = stream;
|
} else ctx.body = stream;
|
||||||
// FIXME: should pass type check
|
// FIXME: should pass type check
|
||||||
await (this.ctx.parallel as any)('connection/active', h as any);
|
await (this.ctx.parallel as any)('connection/active', h as any);
|
||||||
|
h.active = true;
|
||||||
if (layer) {
|
if (layer) {
|
||||||
if (conn.readyState === conn.OPEN) {
|
if (conn.readyState === conn.OPEN) {
|
||||||
conn.on('close', clean);
|
conn.on('close', () => clean());
|
||||||
|
conn.on('error', (err) => clean(err));
|
||||||
conn.resume();
|
conn.resume();
|
||||||
} else clean();
|
} else clean();
|
||||||
} else stream.on('close', clean);
|
} else {
|
||||||
|
stream.on('close', () => clean());
|
||||||
|
stream.on('error', (err) => clean(err));
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await h.onerror(e);
|
// error during initialization (prepare, hooks)
|
||||||
if (!layer) ctx.status = 500;
|
await clean(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ class SystemConfigHandler extends SystemHandler {
|
|||||||
@requireSudo
|
@requireSudo
|
||||||
async get() {
|
async get() {
|
||||||
this.response.template = 'manage_config.html';
|
this.response.template = 'manage_config.html';
|
||||||
let value = this.ctx.config.configSource;
|
let value;
|
||||||
|
|
||||||
const processNode = (node: any, schema: Schema<any, any>, parent?: any, accessKey?: string) => {
|
const processNode = (node: any, schema: Schema<any, any>, parent?: any, accessKey?: string) => {
|
||||||
if (['union', 'intersect'].includes(schema.type)) {
|
if (['union', 'intersect'].includes(schema.type)) {
|
||||||
@@ -199,7 +199,7 @@ class SystemConfigHandler extends SystemHandler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
value = Schema.intersect(this.ctx.config.settings)(yaml.load(value));
|
value = Schema.intersect(this.ctx.config.settings)(yaml.load(this.ctx.config.configSource));
|
||||||
for (const schema of this.ctx.config.settings) processNode(value, schema);
|
for (const schema of this.ctx.config.settings) processNode(value, schema);
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
this.response.body = {
|
this.response.body = {
|
||||||
@@ -218,7 +218,7 @@ class SystemConfigHandler extends SystemHandler {
|
|||||||
for (const item of schema.list) processNode(node, old, item, parent, accessKey);
|
for (const item of schema.list) processNode(node, old, item, parent, accessKey);
|
||||||
}
|
}
|
||||||
if (parent && (schema.meta.secret === true || schema.meta.role === 'secret')) {
|
if (parent && (schema.meta.secret === true || schema.meta.role === 'secret')) {
|
||||||
if (node === '[hidden]') parent[accessKey] = old[accessKey];
|
if (node === '[hidden]') parent[accessKey] = old;
|
||||||
// TODO support more types
|
// TODO support more types
|
||||||
}
|
}
|
||||||
if (schema.type === 'object') {
|
if (schema.type === 'object') {
|
||||||
|
|||||||
@@ -291,9 +291,8 @@ const oi = buildContestRule({
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!detail[j.pid] || detail[j.pid].score < j.score || this.submitAfterAccept) {
|
if (!detail[j.pid] || detail[j.pid].score < j.score || this.submitAfterAccept) {
|
||||||
detail[j.pid] = j;
|
detail[j.pid] = { ...j };
|
||||||
display[j.pid] ||= {};
|
display[j.pid] = { ...j };
|
||||||
display[j.pid] = j;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const i in display) {
|
for (const i in display) {
|
||||||
@@ -360,7 +359,7 @@ const oi = buildContestRule({
|
|||||||
accepted[s.pid] = true;
|
accepted[s.pid] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const tsddict = (config.lockAt ? tsdoc.display : tsdoc.detail) || {};
|
const tsddict = ((config.lockAt && isLocked(tdoc, new Date())) ? tsdoc.display : tsdoc.detail) || {};
|
||||||
for (const pid of tdoc.pids) {
|
for (const pid of tdoc.pids) {
|
||||||
const index = `${tsdoc.uid}/${tdoc.domainId}/${pid}`;
|
const index = `${tsdoc.uid}/${tdoc.domainId}/${pid}`;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||||
|
|||||||
@@ -158,11 +158,11 @@ export default class HMR extends Service {
|
|||||||
for (const filename in require.cache) {
|
for (const filename in require.cache) {
|
||||||
const module = require.cache[filename];
|
const module = require.cache[filename];
|
||||||
const plugin = unwrapExports(module.exports);
|
const plugin = unwrapExports(module.exports);
|
||||||
if (typeof plugin !== 'object' || !plugin || !('apply' in plugin)) continue;
|
if (!plugin) continue;
|
||||||
const runtime = this.ctx.registry.get(plugin);
|
const runtime = this.ctx.registry.get(plugin);
|
||||||
if (!runtime || this.declined.has(filename)) continue;
|
if (!runtime || this.declined.has(filename)) continue;
|
||||||
pending.set(filename, plugin);
|
pending.set(filename, plugin);
|
||||||
if (!plugin || !('sideEffect' in plugin) || !plugin['sideEffect']) this.declined.add(filename);
|
if (!plugin?.sideEffect) this.declined.add(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [filename, plugin] of pending) {
|
for (const [filename, plugin] of pending) {
|
||||||
|
|||||||
Reference in new issue
Block a user