refactor: 턴 경계와 12턴 묶음을 보존하는 2배속 복구 구현
This commit is contained in:
@@ -93,6 +93,7 @@ export class DatabaseTurnDaemonLease {
|
||||
ON CONFLICT ("profile") DO UPDATE
|
||||
SET
|
||||
"owner_id" = EXCLUDED."owner_id",
|
||||
"clock_ready" = FALSE,
|
||||
"lease_until" = EXCLUDED."lease_until",
|
||||
"fencing_epoch" = CASE
|
||||
WHEN "turn_daemon_lease"."owner_id" = EXCLUDED."owner_id"
|
||||
@@ -126,6 +127,14 @@ export class DatabaseTurnDaemonLease {
|
||||
return this.token ? { ...this.token } : null;
|
||||
}
|
||||
|
||||
async markClockReady(): Promise<void> {
|
||||
await this.db.$transaction(async (db) => {
|
||||
await this.assertActive(db);
|
||||
const token = this.getToken()!;
|
||||
await db.turnDaemonLease.update({ where: { profile: token.profile }, data: { clockReady: true } });
|
||||
});
|
||||
}
|
||||
|
||||
isLost(): boolean {
|
||||
return this.lost;
|
||||
}
|
||||
|
||||
@@ -170,6 +170,11 @@ export class TurnDaemonLifecycle {
|
||||
await this.clock.sleepMs(500);
|
||||
continue;
|
||||
}
|
||||
if (gameClock?.mode === 'realtime' && gameClock.startsAt && wallNow < gameClock.startsAt) {
|
||||
this.status.nextTurnTime = gameClock.startsAt.toISOString();
|
||||
await this.clock.sleepMs(Math.min(500, gameClock.startsAt.getTime() - nowMs));
|
||||
continue;
|
||||
}
|
||||
// 수동 실행 요청도 가오픈·정지·재조정의 턴 실행 gate를 통과해야 한다.
|
||||
// 사용자 명령 처리는 루프 시작에서 계속하되 시간 진행은 여기서 분리한다.
|
||||
if (this.pendingRun) {
|
||||
@@ -219,7 +224,10 @@ export class TurnDaemonLifecycle {
|
||||
continue;
|
||||
}
|
||||
|
||||
const command = await this.controlQueue.waitFor(Math.max(0, nextTurnMs - gameNowMs));
|
||||
const wallDeadline = await this.stateStore.projectGameDeadline?.(nextRunTime);
|
||||
const command = await this.controlQueue.waitFor(
|
||||
Math.max(0, wallDeadline ? wallDeadline.getTime() - nowMs : nextTurnMs - gameNowMs)
|
||||
);
|
||||
if (command) {
|
||||
await this.handleCommand(command);
|
||||
}
|
||||
|
||||
@@ -72,11 +72,13 @@ export interface TurnStateStore {
|
||||
phase?: GameClockPhase;
|
||||
revision?: number;
|
||||
deadlineGeneration?: number;
|
||||
startsAt?: Date;
|
||||
}>;
|
||||
promotePreopenAtOpening?(wallNow: Date): Promise<boolean>;
|
||||
shouldRebaseRealtimeBacklog?(wallNow: Date): Promise<boolean>;
|
||||
rebaseRealtimeBacklog?(wallNow: Date): Promise<RealtimeBacklogRebaseResult | null>;
|
||||
advanceGameClockTo?(target: Date, wallNow: Date): Promise<void>;
|
||||
projectGameDeadline?(gameTime: Date): Promise<Date>;
|
||||
}
|
||||
|
||||
export interface TurnDaemonControlQueue {
|
||||
|
||||
Reference in New Issue
Block a user