perf: 실시간 접속 확인에서 불필요한 context 조회를 제거
This commit is contained in:
@@ -85,6 +85,8 @@ export type DatabaseClient = InfraDatabaseClient;
|
||||
export interface GameApiContext {
|
||||
requestId?: string;
|
||||
generalAccessTracking?: boolean;
|
||||
/** Request-local identity already resolved by the realtime access gate. */
|
||||
realtimeAccessGeneralId?: number;
|
||||
db: DatabaseClient;
|
||||
redis: RedisConnector['client'];
|
||||
turnDaemon: TurnDaemonTransport;
|
||||
|
||||
@@ -9,26 +9,21 @@ import { getTurnCommandTable } from '../turns/index.js';
|
||||
|
||||
const zRevision = z.string().regex(/^[A-Za-z0-9_-]{22}$/u);
|
||||
|
||||
const zContextBundleInput = z
|
||||
.object({
|
||||
include: z.object({
|
||||
context: z.boolean(),
|
||||
commandTable: z.boolean(),
|
||||
boardAccess: z.boolean(),
|
||||
}),
|
||||
known: z
|
||||
.object({
|
||||
context: zRevision.optional(),
|
||||
commandTable: zRevision.optional(),
|
||||
boardAccess: zRevision.optional(),
|
||||
})
|
||||
.optional(),
|
||||
forceSnapshot: z.boolean().optional(),
|
||||
})
|
||||
.refine((input) => Object.values(input.include).some(Boolean), {
|
||||
message: 'At least one dashboard context slice must be requested.',
|
||||
path: ['include'],
|
||||
});
|
||||
const zContextBundleInput = z.object({
|
||||
include: z.object({
|
||||
context: z.boolean(),
|
||||
commandTable: z.boolean(),
|
||||
boardAccess: z.boolean(),
|
||||
}),
|
||||
known: z
|
||||
.object({
|
||||
context: zRevision.optional(),
|
||||
commandTable: zRevision.optional(),
|
||||
boardAccess: zRevision.optional(),
|
||||
})
|
||||
.optional(),
|
||||
forceSnapshot: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const dashboardRouter = router({
|
||||
getContextBundleDelta: accessLimitAuthedProcedure.input(zContextBundleInput).query(async ({ ctx, input }) => {
|
||||
@@ -37,8 +32,20 @@ export const dashboardRouter = router({
|
||||
throw new TRPCError({ code: 'UNAUTHORIZED' });
|
||||
}
|
||||
|
||||
const currentContext = await getGeneralContext(ctx);
|
||||
const generalId = currentContext?.general.id ?? null;
|
||||
const includesProjection = Object.values(input.include).some(Boolean);
|
||||
const currentContext = input.include.context ? await getGeneralContext(ctx) : undefined;
|
||||
const generalId =
|
||||
currentContext?.general.id ??
|
||||
ctx.realtimeAccessGeneralId ??
|
||||
(includesProjection
|
||||
? (
|
||||
await ctx.db.general.findFirst({
|
||||
where: { userId: viewerId },
|
||||
orderBy: { id: 'asc' },
|
||||
select: { id: true },
|
||||
})
|
||||
)?.id ?? null
|
||||
: null);
|
||||
const [commandTable, boardAccess] = await Promise.all([
|
||||
input.include.commandTable && generalId ? getTurnCommandTable(ctx, generalId) : Promise.resolve(undefined),
|
||||
input.include.boardAccess && generalId ? getBoardAccess(ctx) : Promise.resolve(undefined),
|
||||
|
||||
@@ -94,6 +94,7 @@ export const generalAccessLimitEndpoints = new Set<GeneralAccessEndpoint>([
|
||||
export const generalAccessLimitBeforeRecordEndpoints = new Set<GeneralAccessEndpoint>(['general.getFrontStatus']);
|
||||
|
||||
export type GeneralAccessState = {
|
||||
generalId: number;
|
||||
refreshScore: number;
|
||||
refreshLimit: number;
|
||||
level: AccessLimitLevel;
|
||||
@@ -194,6 +195,7 @@ export const getGeneralAccessState = async (
|
||||
: (access?.refreshScore ?? 0);
|
||||
const refreshLimit = resolveAccessRefreshLimit(worldState.tickSeconds, asRecord(worldState.meta).refreshLimit);
|
||||
return {
|
||||
generalId: general.id,
|
||||
refreshScore,
|
||||
refreshLimit,
|
||||
level: resolveAccessLimitLevel(refreshScore, refreshLimit),
|
||||
|
||||
@@ -126,7 +126,12 @@ const generalAccessLimitMiddleware = t.middleware(async ({ ctx, next }) => {
|
||||
message: formatGeneralAccessLimitMessage(state),
|
||||
});
|
||||
}
|
||||
return next();
|
||||
return next({
|
||||
ctx: {
|
||||
...ctx,
|
||||
...(state ? { realtimeAccessGeneralId: state.generalId } : {}),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
export const router = t.router;
|
||||
|
||||
Reference in New Issue
Block a user