Skip to content

Commit

Permalink
Merge pull request #156 from martius-lab/fkloss/fix_game_save_issue
Browse files Browse the repository at this point in the history
Fix game not being ended properly if saving game data fails
  • Loading branch information
luator authored Feb 3, 2025
2 parents 9bcc7da + 432e6c5 commit 649bf8a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 22 deletions.
10 changes: 7 additions & 3 deletions comprl-web-reflex/comprl_web/pages/games.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ def show_game(game: GameInfo) -> rx.Component:
rx.table.cell(game.time),
rx.table.cell(game.id),
rx.table.cell(
rx.button(
"Download game data",
on_click=lambda: UserGamesState.download_game(game.id),
rx.cond(
game.has_game_file,
rx.button(
"Download game data",
on_click=lambda: UserGamesState.download_game(game.id),
),
rx.text("No game data", align="center", style={"font-style": "italic"}),
)
),
)
Expand Down
13 changes: 10 additions & 3 deletions comprl-web-reflex/comprl_web/protected_state.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""State for the protected pages."""

import dataclasses
import pathlib
from typing import Sequence

import reflex as rx
Expand All @@ -27,6 +28,7 @@ class GameInfo:
result: str
time: str
id: str
has_game_file: bool


class ProtectedState(reflex_local_auth.LocalAuthState):
Expand Down Expand Up @@ -217,6 +219,9 @@ def clear_search(self):
self.search_id = ""
self.load_user_games()

def _get_game_file_path(self, game_id: str) -> pathlib.Path:
return config.get_config().data_dir / "game_actions" / f"{game_id}.pkl"

@rx.event
def load_user_games(self) -> None:
self.user_games = []
Expand All @@ -230,26 +235,28 @@ def load_user_games(self) -> None:
else:
result = "Unknown"

game_file_exists = self._get_game_file_path(game.game_id).exists()

self.user_games.append(
GameInfo(
game.user1_.username,
game.user2_.username,
result,
str(game.start_time.strftime("%Y-%m-%d %H:%M:%S")),
str(game.game_id),
game_file_exists,
)
)

self.total_items = self._get_num_user_games()

@rx.event
def download_game(self, game_id: str):
game_file_name = f"{game_id}.pkl"
game_file_path = config.get_config().data_dir / "game_actions" / game_file_name
game_file_path = self._get_game_file_path(game_id)

try:
data = game_file_path.read_bytes()
except Exception:
raise RuntimeError("Game file not found") from None

return rx.download(filename=game_file_name, data=data)
return rx.download(filename=game_file_path.name, data=data)
37 changes: 21 additions & 16 deletions comprl/src/comprl/server/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,22 +150,27 @@ def _end(self, reason="unknown"):
Args:
reason (str): The reason why the game has ended. Defaults to "unknown".
"""

# store actions:
# TODO: maybe add multithreading here to ease the load on the main server thread
# as storing the actions can take a while
self.game_info["actions"] = np.array(self.all_actions)

data_dir = get_config().data_dir
# should already be checked during config loading but just to be sure
assert data_dir.is_dir(), f"data_dir '{data_dir}' is not a directory"
game_actions_dir = data_dir / "game_actions"
game_actions_dir.mkdir(exist_ok=True)
output_file = game_actions_dir / f"{self.id}.pkl"

logging.debug("Save game actions to %s", output_file)
with open(output_file, "wb") as f:
pickle.dump(self.game_info, f)
if self.disconnected_player_id is None:
# store actions:
try:
# TODO: maybe add multithreading here to ease the load on the main
# server thread as storing the actions can take a while
self.game_info["actions"] = np.array(self.all_actions)

data_dir = get_config().data_dir
# should already be checked during config loading but just to be sure
assert data_dir.is_dir(), f"data_dir '{data_dir}' is not a directory"
game_actions_dir = data_dir / "game_actions"
game_actions_dir.mkdir(exist_ok=True)
output_file = game_actions_dir / f"{self.id}.pkl"

logging.debug("Save game actions to %s", output_file)
with open(output_file, "wb") as f:
pickle.dump(self.game_info, f)
except Exception as e:
logging.error(
"Error while saving game actions: %s | game_id=%s", e, self.id
)

# notify end
for callback in self.finish_callbacks:
Expand Down

0 comments on commit 649bf8a

Please sign in to comment.