fix circular import errors so the server and start again

This commit is contained in:
2026-04-06 04:30:02 +02:00
parent 98be2fe6fe
commit 43c7720480
8 changed files with 39 additions and 18 deletions
+2 -1
View File
@@ -1,7 +1,8 @@
from snakes.TemplateSnake import TemplateSnake
from datetime import datetime from datetime import datetime
class GameBoard: class GameBoard:
def __init__(self, game_id:str, width:int, height:int, ruleset:dict, source:str, map:str, snake_class): def __init__(self, game_id:str, width:int, height:int, ruleset:dict, source:str, map:str, snake_class:TemplateSnake):
self.id = game_id self.id = game_id
self.width = width self.width = width
self.height = height self.height = height
+4 -1
View File
@@ -1,9 +1,12 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from server.GameBoard import GameBoard from server.GameBoard import GameBoard
class Dataset: class Dataset:
VALID_MOVES = {"up", "down", "left", "right"} VALID_MOVES = {"up", "down", "left", "right"}
def __init__(self, game_board:GameBoard): def __init__(self, game_board:'GameBoard'):
self.game_board = game_board self.game_board = game_board
def _did_we_win(self): def _did_we_win(self):
@@ -1,10 +1,13 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from server.GameBoard import GameBoard from server.GameBoard import GameBoard
class MemoryGameBoardStore: class MemoryGameBoardStore:
def __init__(self, **kwargs): def __init__(self, **kwargs):
self._state:dict[str, object] = {} self._state:dict[str, object] = {}
async def save(self, game_id:str, game_board:GameBoard) -> None: async def save(self, game_id:str, game_board:'GameBoard') -> None:
self._state[game_id] = game_board self._state[game_id] = game_board
async def load(self, game_id:str): async def load(self, game_id:str):
@@ -1,6 +1,9 @@
from server.GameBoard import GameBoard from typing import TYPE_CHECKING
import inspect, pickle import inspect, pickle
if TYPE_CHECKING:
from server.GameBoard import GameBoard
class RedisGameBoardStore: class RedisGameBoardStore:
def __init__(self, redis_url:str="redis://localhost:6379/0", key_prefix:str="snake:gameboard", ttl_seconds:int=900, **kwargs): def __init__(self, redis_url:str="redis://localhost:6379/0", key_prefix:str="snake:gameboard", ttl_seconds:int=900, **kwargs):
self.redis_url = redis_url self.redis_url = redis_url
@@ -23,7 +26,7 @@ class RedisGameBoardStore:
def _key(self, game_id:str) -> str: def _key(self, game_id:str) -> str:
return f"{self.key_prefix}:{game_id}" return f"{self.key_prefix}:{game_id}"
async def save(self, game_id:str, game_board:GameBoard) -> None: async def save(self, game_id:str, game_board:'GameBoard') -> None:
redis = await self._get_redis() redis = await self._get_redis()
payload = pickle.dumps(game_board, protocol=pickle.HIGHEST_PROTOCOL) payload = pickle.dumps(game_board, protocol=pickle.HIGHEST_PROTOCOL)
await redis.set(self._key(game_id), payload, ex=self.ttl_seconds) await redis.set(self._key(game_id), payload, ex=self.ttl_seconds)
+1 -1
View File
@@ -4,7 +4,7 @@ import time
from server.metrics import MetricsCollector from server.metrics import MetricsCollector
from server.GameBoard import GameBoard from server.GameBoard import GameBoard
from storage import StorageLoader from server.storage import StorageLoader
from snakes import SnakeBuilder from snakes import SnakeBuilder
class GameRuntimeService: class GameRuntimeService:
+11 -7
View File
@@ -1,5 +1,9 @@
from server.dataset.Dataset import Dataset from typing import TYPE_CHECKING
if TYPE_CHECKING:
from server.GameBoard import GameBoard from server.GameBoard import GameBoard
from server.dataset.Dataset import Dataset
from server.Files import save_file from server.Files import save_file
import aiofiles import aiofiles
@@ -21,7 +25,7 @@ class LocalStorage:
self.dataset_compress_rotated = os.getenv("DATASET_COMPRESS_ROTATED", "true").strip().lower() in ("1", "true", "yes", "on") self.dataset_compress_rotated = os.getenv("DATASET_COMPRESS_ROTATED", "true").strip().lower() in ("1", "true", "yes", "on")
self.dataset_max_bytes = int(float(os.getenv("DATASET_JSONL_MAX_MB", "50")) * 1024 * 1024) self.dataset_max_bytes = int(float(os.getenv("DATASET_JSONL_MAX_MB", "50")) * 1024 * 1024)
def _get_active_dataset_path(self, game_board:GameBoard): def _get_active_dataset_path(self, game_board:'GameBoard'):
if not self.dataset_rotate_daily: if not self.dataset_rotate_daily:
return self.dataset_jsonl_path return self.dataset_jsonl_path
@@ -60,7 +64,7 @@ class LocalStorage:
self._gzip_file(os.path.join(folder, name)) self._gzip_file(os.path.join(folder, name))
async def _rotate_if_needed(self, active_path:str, game_board:GameBoard): async def _rotate_if_needed(self, active_path:str, game_board:'GameBoard'):
if self.dataset_max_bytes <= 0: if self.dataset_max_bytes <= 0:
return return
if not await aiofiles.os.path.exists(active_path): if not await aiofiles.os.path.exists(active_path):
@@ -81,7 +85,7 @@ class LocalStorage:
if self.dataset_compress_rotated: if self.dataset_compress_rotated:
self._gzip_file(rotated_path) self._gzip_file(rotated_path)
def _build_dataset_rows(self, dataset_payload:dict, game_board:GameBoard): def _build_dataset_rows(self, dataset_payload:dict, game_board:'GameBoard'):
game_info = dataset_payload.get("game", {}) game_info = dataset_payload.get("game", {})
snake_info = dataset_payload.get("snake", {}) snake_info = dataset_payload.get("snake", {})
@@ -102,7 +106,7 @@ class LocalStorage:
}) })
return rows return rows
async def _append_dataset_jsonl(self, dataset_payload:dict, game_board:GameBoard): async def _append_dataset_jsonl(self, dataset_payload:dict, game_board:'GameBoard'):
rows = self._build_dataset_rows(dataset_payload, game_board) rows = self._build_dataset_rows(dataset_payload, game_board)
if len(rows) == 0: if len(rows) == 0:
return return
@@ -116,7 +120,7 @@ class LocalStorage:
for row in rows: for row in rows:
await f.write(json.dumps(row, ensure_ascii=False) + "\n") await f.write(json.dumps(row, ensure_ascii=False) + "\n")
def _get_correct_folder_for_save_file(self, game_board:GameBoard, file_name:str, game_type:str, leader_board:bool, winner:bool): def _get_correct_folder_for_save_file(self, game_board:'GameBoard', file_name:str, game_type:str, leader_board:bool, winner:bool):
storage_folder = self.file_path storage_folder = self.file_path
if leader_board: if leader_board:
storage_folder = os.path.join(storage_folder, "00_Leaderboards") storage_folder = os.path.join(storage_folder, "00_Leaderboards")
@@ -136,7 +140,7 @@ class LocalStorage:
return os.path.join(storage_folder, file_name) return os.path.join(storage_folder, file_name)
async def save(self, game_board:GameBoard): async def save(self, game_board:'GameBoard'):
game_type = game_board.get_type_of_game() game_type = game_board.get_type_of_game()
dataset = Dataset(game_board).build(only_good_moves=True) dataset = Dataset(game_board).build(only_good_moves=True)
+4 -1
View File
@@ -1,6 +1,9 @@
from .LocalStorage import LocalStorage
from .EdgeDB import EdgeDB
class StorageLoader: class StorageLoader:
@classmethod @classmethod
def build(self, selected_storage: str): def build(self, selected_storage:str) -> LocalStorage|EdgeDB:
storage_module = __import__(f"server.storage.{selected_storage}", fromlist=[selected_storage]) storage_module = __import__(f"server.storage.{selected_storage}", fromlist=[selected_storage])
storage_class = getattr(storage_module, selected_storage) storage_class = getattr(storage_module, selected_storage)
return storage_class return storage_class
+5 -1
View File
@@ -1,4 +1,8 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from server.GameBoard import GameBoard from server.GameBoard import GameBoard
import random import random
class TemplateSnake: class TemplateSnake:
@@ -22,7 +26,7 @@ class TemplateSnake:
def add_calculations(self, calculations:dict): def add_calculations(self, calculations:dict):
self.calculations.append(calculations) self.calculations.append(calculations)
def choose_move(self, game_data:GameBoard): def choose_move(self, game_data:'GameBoard'):
self.game_board = game_data self.game_board = game_data
self.calculations = [] self.calculations = []
self.eat_the_snake_overwrite = False self.eat_the_snake_overwrite = False