diff --git a/packages/hydrooj/src/context.ts b/packages/hydrooj/src/context.ts index 1c8a5faff..4c7346456 100644 --- a/packages/hydrooj/src/context.ts +++ b/packages/hydrooj/src/context.ts @@ -61,7 +61,9 @@ export class ApiMixin extends Service { setImmediate = T(setImmediate, clearImmediate); provideModule = T(provideModule); injectUI = T(inject); - broadcast = (event: keyof EventMap, ...payload) => this.ctx.emit('bus/broadcast', event, payload); + broadcast = (event: keyof EventMap, ...payload) => + this.ctx.emit('bus/broadcast', event, payload, process.env.TRACE_BROADCAST ? new Error().stack : null); + constructor(ctx) { super(ctx, '$api', true); ctx.mixin('$api', ['addScript', 'setImmediate', 'provideModule', 'injectUI', 'broadcast']); diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index 9be64681e..354c1da9e 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -639,6 +639,7 @@ export interface EventDoc { event: number | string; payload: string; expire: Date; + trace?: string; } export interface OpCountDoc { diff --git a/packages/hydrooj/src/model/task.ts b/packages/hydrooj/src/model/task.ts index e9bb19404..57831b991 100644 --- a/packages/hydrooj/src/model/task.ts +++ b/packages/hydrooj/src/model/task.ts @@ -144,12 +144,13 @@ const id = process.env.exec_mode === 'cluster_mode' ? hostname() : nanoid(); export async function apply(ctx: Context) { ctx.on('domain/delete', (domainId) => coll.deleteMany({ domainId })); - ctx.on('bus/broadcast', (event, payload) => { + ctx.on('bus/broadcast', (event, payload, trace) => { collEvent.insertOne({ ack: [id], event, payload: BSON.EJSON.stringify(payload), expire: new Date(Date.now() + 10000), + trace, }); }); diff --git a/packages/hydrooj/src/service/bus.ts b/packages/hydrooj/src/service/bus.ts index feeac7790..2b34f728d 100644 --- a/packages/hydrooj/src/service/bus.ts +++ b/packages/hydrooj/src/service/bus.ts @@ -38,7 +38,7 @@ export interface EventMap extends KnownHandlerEvents { 'database/config': () => VoidReturn 'system/setting': (args: Record) => VoidReturn - 'bus/broadcast': (event: keyof EventMap | keyof ServerEvents, payload: any) => VoidReturn + 'bus/broadcast': (event: keyof EventMap | keyof ServerEvents, payload: any, trace?: string) => VoidReturn 'monitor/update': (type: 'server' | 'judge', $set: any) => VoidReturn 'monitor/collect': (info: any) => VoidReturn 'api/update': () => void;