mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-27 06:14:36 +00:00
refactor(worker): remove heartbeat mechanism and implement pending turn processing
- Removed the heartbeat functionality from the ClientGameRunner and WorkerClient. - Introduced a new processPendingTurns function in Worker.worker.ts to handle turn execution more efficiently. - Added a hasPendingTurns method in GameRunner to check for unprocessed turns. - Updated WorkerMessages to remove heartbeat message type.
This commit is contained in:
@@ -381,15 +381,6 @@ export class ClientGameRunner {
|
||||
}
|
||||
});
|
||||
|
||||
const worker = this.worker;
|
||||
const keepWorkerAlive = () => {
|
||||
if (this.isActive) {
|
||||
worker.sendHeartbeat();
|
||||
requestAnimationFrame(keepWorkerAlive);
|
||||
}
|
||||
};
|
||||
requestAnimationFrame(keepWorkerAlive);
|
||||
|
||||
const onconnect = () => {
|
||||
console.log("Connected to game server!");
|
||||
this.transport.rejoinGame(this.turnsSeen);
|
||||
|
||||
@@ -145,7 +145,7 @@ export class GameRunner {
|
||||
console.error("Game tick error:", error);
|
||||
}
|
||||
this.isExecuting = false;
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.game.inSpawnPhase() && this.game.ticks() % 2 === 0) {
|
||||
@@ -268,4 +268,8 @@ export class GameRunner {
|
||||
}
|
||||
return player.bestTransportShipSpawn(targetTile);
|
||||
}
|
||||
|
||||
public hasPendingTurns(): boolean {
|
||||
return this.currTurn < this.turns.length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
const ctx: Worker = self as any;
|
||||
let gameRunner: Promise<GameRunner> | null = null;
|
||||
const mapLoader = new FetchGameMapLoader(`/maps`, version);
|
||||
const MAX_TICKS_PER_HEARTBEAT = 4;
|
||||
let isProcessingTurns = false;
|
||||
|
||||
function gameUpdate(gu: GameUpdateViewData | ErrorUpdate) {
|
||||
// skip if ErrorUpdate
|
||||
@@ -33,23 +33,33 @@ function sendMessage(message: WorkerMessage) {
|
||||
ctx.postMessage(message);
|
||||
}
|
||||
|
||||
async function processPendingTurns() {
|
||||
if (isProcessingTurns) {
|
||||
return;
|
||||
}
|
||||
if (!gameRunner) {
|
||||
return;
|
||||
}
|
||||
|
||||
const gr = await gameRunner;
|
||||
if (!gr || !gr.hasPendingTurns()) {
|
||||
return;
|
||||
}
|
||||
|
||||
isProcessingTurns = true;
|
||||
try {
|
||||
while (gr.hasPendingTurns()) {
|
||||
gr.executeNextTick();
|
||||
}
|
||||
} finally {
|
||||
isProcessingTurns = false;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.addEventListener("message", async (e: MessageEvent<MainThreadMessage>) => {
|
||||
const message = e.data;
|
||||
|
||||
switch (message.type) {
|
||||
case "heartbeat": {
|
||||
const gr = await gameRunner;
|
||||
if (!gr) {
|
||||
break;
|
||||
}
|
||||
const ticksToRun = Math.min(gr.pendingTurns(), MAX_TICKS_PER_HEARTBEAT);
|
||||
for (let i = 0; i < ticksToRun; i++) {
|
||||
if (!gr.executeNextTick()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "init":
|
||||
try {
|
||||
gameRunner = createGameRunner(
|
||||
@@ -62,6 +72,7 @@ ctx.addEventListener("message", async (e: MessageEvent<MainThreadMessage>) => {
|
||||
type: "initialized",
|
||||
id: message.id,
|
||||
} as InitializedMessage);
|
||||
processPendingTurns();
|
||||
return gr;
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -78,6 +89,7 @@ ctx.addEventListener("message", async (e: MessageEvent<MainThreadMessage>) => {
|
||||
try {
|
||||
const gr = await gameRunner;
|
||||
await gr.addTurn(message.turn);
|
||||
processPendingTurns();
|
||||
} catch (error) {
|
||||
console.error("Failed to process turn:", error);
|
||||
throw error;
|
||||
|
||||
@@ -102,12 +102,6 @@ export class WorkerClient {
|
||||
});
|
||||
}
|
||||
|
||||
sendHeartbeat() {
|
||||
this.worker.postMessage({
|
||||
type: "heartbeat",
|
||||
});
|
||||
}
|
||||
|
||||
playerProfile(playerID: number): Promise<PlayerProfile> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isInitialized) {
|
||||
|
||||
@@ -9,7 +9,6 @@ import { GameUpdateViewData } from "../game/GameUpdates";
|
||||
import { ClientID, GameStartInfo, Turn } from "../Schemas";
|
||||
|
||||
export type WorkerMessageType =
|
||||
| "heartbeat"
|
||||
| "init"
|
||||
| "initialized"
|
||||
| "turn"
|
||||
@@ -31,10 +30,6 @@ interface BaseWorkerMessage {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export interface HeartbeatMessage extends BaseWorkerMessage {
|
||||
type: "heartbeat";
|
||||
}
|
||||
|
||||
// Messages from main thread to worker
|
||||
export interface InitMessage extends BaseWorkerMessage {
|
||||
type: "init";
|
||||
@@ -114,7 +109,6 @@ export interface TransportShipSpawnResultMessage extends BaseWorkerMessage {
|
||||
|
||||
// Union types for type safety
|
||||
export type MainThreadMessage =
|
||||
| HeartbeatMessage
|
||||
| InitMessage
|
||||
| TurnMessage
|
||||
| PlayerActionsMessage
|
||||
|
||||
Reference in New Issue
Block a user