Skip to content

Commit

Permalink
Fix bughouse game caching
Browse files Browse the repository at this point in the history
  • Loading branch information
gbtami committed Dec 29, 2024
1 parent 01cedea commit 4eeb58a
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 46 deletions.
25 changes: 1 addition & 24 deletions server/bug/game_bug.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,30 +275,7 @@ async def save_game(self):
response = {"type": "g_cnt", "cnt": self.app_state.g_cnt[0]}
await self.app_state.lobby.lobby_broadcast(response)

async def remove(keep_time):
# Keep it in our games dict a little to let players get the last board
# not to mention that BOT players want to abort games after 20 sec inactivity
await asyncio.sleep(keep_time)

try:
del self.games[self.id]
except KeyError:
log.info("Failed to del %s from games", self.id)

if self.bot_game:
try:
if self.wplayerA.bot:
del self.wplayerA.game_queues[self.id]
if self.bplayerA.bot:
del self.bplayerA.game_queues[self.id]
if self.wplayerB.bot:
del self.wplayerB.game_queues[self.id]
if self.bplayerB.bot:
del self.bplayerB.game_queues[self.id]
except KeyError:
log.info("Failed to del %s from game_queues", self.id)

self.remove_task = asyncio.create_task(remove(KEEP_TIME), name="remove-game-%s" % self.id)
asyncio.create_task(self.app_state.remove_from_cache(self), name="game-remove-%s" % self.id)

# always save them, even if no moves - todo: will optimize eventually, just want it simple now
# and have trace of all games for later investigation
Expand Down
5 changes: 5 additions & 0 deletions server/bug/utils_bug.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import logging
import random
from datetime import timezone
Expand Down Expand Up @@ -237,6 +238,10 @@ async def load_game_bug(app_state: PychessGlobalAppState, game_id):
game.steps[idx]["chat"].append(
{"message": c["m"], "username": c["u"], "time": c["t"]}
)

app_state.games[game_id] = game
if game.status > STARTED:
asyncio.create_task(app_state.remove_from_cache(game), name="game-remove-%s" % game_id)
log.debug("load_game_bug parse DONE")

return game
Expand Down
25 changes: 3 additions & 22 deletions server/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
log = logging.getLogger(__name__)

MAX_PLY = 600
KEEP_TIME = 1800 # keep game in app[games_key] for KEEP_TIME secs

INVALID_PAWN_DROP_MATE = (
("P@", "shogi"),
Expand Down Expand Up @@ -480,27 +479,7 @@ async def save_game(self):
response = {"type": "g_cnt", "cnt": self.app_state.g_cnt[0]}
await self.app_state.lobby.lobby_broadcast(response)

async def remove(keep_time):
# Keep it in our games dict a little to let players get the last board
# not to mention that BOT players want to abort games after 20 sec inactivity
await asyncio.sleep(keep_time)

if self.id == self.app_state.tv:
self.app_state.tv = None

if self.id in self.app_state.games:
del self.app_state.games[self.id]

if self.bot_game:
try:
if self.wplayer.bot:
del self.wplayer.game_queues[self.id]
if self.bplayer.bot:
del self.bplayer.game_queues[self.id]
except KeyError:
log.error("Failed to del %s from game_queues", self.id)

self.remove_task = asyncio.create_task(remove(KEEP_TIME), name="game-remove-%s" % self.id)
asyncio.create_task(self.app_state.remove_from_cache(self), name="game-remove-%s" % self.id)

if self.board.ply < 3 and (self.app_state.db is not None) and (self.tournamentId is None):
result = await self.app_state.db.game.delete_one({"_id": self.id})
Expand Down Expand Up @@ -1023,6 +1002,7 @@ def stop_manual_count(self):
self.board.count_started = -1

def create_steps(self):
log.debug("create_steps() START")
if self.mct is not None:
manual_count_toggled = iter(self.mct)
count_started = -1
Expand Down Expand Up @@ -1103,6 +1083,7 @@ def create_steps(self):
self.board.move_stack,
)
break
log.debug("create_steps() OK")

def get_board(self, full=False):
if len(self.board.move_stack) > 0 and len(self.steps) == 1:
Expand Down
21 changes: 21 additions & 0 deletions server/pychess_global_app_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@

log = logging.getLogger(__name__)

GAME_KEEP_TIME = 1800 # keep game in app[games_key] for GAME_KEEP_TIME secs


class PychessGlobalAppState:
def __init__(self, app: web.Application):
Expand Down Expand Up @@ -438,6 +440,25 @@ def __init_users(self) -> Users:
result[NONE_USER].enabled = False
return result

async def remove_from_cache(self, game):
await asyncio.sleep(GAME_KEEP_TIME)

if game.id == self.tv:
self.tv = None

if game.id in self.games:
del self.games[game.id]

if game.bot_game:
try:
for player in game.all_players:
if player.bot:
del player.game_queues[game.id]
except KeyError:
log.error("Failed to del %s from game_queues", game.id)

log.debug("Removed %s OK", game.id)

async def server_shutdown(self):
self.shutdown = True

Expand Down
7 changes: 7 additions & 0 deletions server/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ async def load_game(app_state: PychessGlobalAppState, game_id):
if game_id in app_state.games:
return app_state.games[game_id]

log.debug("load_game() %s from db ", game_id)
doc = await app_state.db.game.find_one({"_id": game_id})

if doc is None:
Expand All @@ -95,6 +96,7 @@ async def load_game(app_state: PychessGlobalAppState, game_id):

return await load_game_bug(app_state, game_id)

log.debug("load_game() parse START")
wp, bp = doc["us"]

wplayer = await app_state.users.get(wp)
Expand Down Expand Up @@ -224,6 +226,11 @@ async def load_game(app_state: PychessGlobalAppState, game_id):

game.loaded_at = datetime.now(timezone.utc)

app_state.games[game_id] = game
if game.status > STARTED:
asyncio.create_task(app_state.remove_from_cache(game), name="game-remove-%s" % game_id)

log.debug("load_game() parse DONE")
return game


Expand Down

0 comments on commit 4eeb58a

Please sign in to comment.