test(clock): exercise suspended lifecycle actions

This commit is contained in:
2026-09-03 17:29:18 +00:00
parent 000e7e8fa5
commit 0aa549a6c5
7 changed files with 1292 additions and 11 deletions
@@ -119,6 +119,18 @@ export class DatabaseTurnDaemonCommandQueue implements TurnDaemonControlQueue, T
const gameplayAllowed = !world || world.clockPhase === 'RUNNING' || world.clockPhase === 'MANUAL';
const suspendedTournamentBetCommand = world?.clockPhase === 'SUSPENDED';
const currentRevision = world?.clockRevision ?? null;
const maintenanceSuspended =
world?.clockPhase === 'SUSPENDED' &&
Boolean(
await transaction.clockSuspension.findFirst({
where: {
status: 'SUSPENDED',
source: 'MAINTENANCE',
sourceRevision: world.clockRevision,
},
select: { id: true },
})
);
const rows = await transaction.$queryRaw<
Array<{
sequence: bigint;
@@ -151,6 +163,30 @@ export class DatabaseTurnDaemonCommandQueue implements TurnDaemonControlQueue, T
AND "event_type" IN ('adjustGeneralResources', 'adjustGeneralMeta')
AND "payload" ->> 'reason' IN ('tournamentBet', 'tournamentBetRollback')
)
OR (
${maintenanceSuspended}
AND "event_type" IN (
'inheritanceAction',
'dropItem',
'changePermission',
'appoint',
'setNationSetting',
'setNpcPolicy'
)
)
OR (
${maintenanceSuspended}
AND "event_type" = 'messageRespond'
AND "payload" ->> 'messageId' ~ '^[1-9][0-9]*$'
AND EXISTS (
SELECT 1
FROM "message_action" AS pending_action
WHERE pending_action."message_id" = ("input_event"."payload" ->> 'messageId')::integer
AND pending_action."status" = 'PENDING'
AND pending_action."clock_revision" = ${currentRevision}
AND pending_action."deadline_generation" = ${world?.deadlineGeneration ?? null}
)
)
OR (
${world?.clockPhase === 'SUSPENDED'}
AND "event_type" = 'messageRespond'
@@ -17,6 +17,7 @@ export interface GatewayProfileGate {
}
const DEFAULT_CACHE_MS = 2000;
const PROFILE_STATUSES_MARKABLE_AS_PAUSED = ['PREOPEN', 'RUNNING', 'PAUSED'] as const;
export const createGatewayProfileGate = async (options: GatewayProfileGateOptions): Promise<GatewayProfileGate> => {
const connector = createGatewayPostgresConnector({
@@ -55,8 +56,11 @@ export const createGatewayProfileGate = async (options: GatewayProfileGateOption
async markPaused(error?: unknown): Promise<void> {
const message = error instanceof Error ? error.message : error ? String(error) : null;
try {
await prisma.gatewayProfile.update({
where: { profileName: options.profileName },
await prisma.gatewayProfile.updateMany({
where: {
profileName: options.profileName,
status: { in: [...PROFILE_STATUSES_MARKABLE_AS_PAUSED] },
},
data: {
status: 'PAUSED',
lastError: message,