Files
snake-python/server/game_board_stats/RedisGameBoardStore.py
T

54 lines
1.7 KiB
Python

from server.GameBoard import GameBoard
import pickle
class RedisGameBoardStore:
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.key_prefix = key_prefix
self.ttl_seconds = max(60, int(ttl_seconds))
self._redis = None
async def _get_redis(self):
if self._redis is not None:
return self._redis
try:
import aioredis # type: ignore[import-not-found]
except ImportError as error: # pragma: no cover
raise RuntimeError("Redis backend selected but 'aioredis' package is not installed") from error
self._redis = aioredis.from_url(self.redis_url)
return self._redis
def _key(self, game_id:str) -> str:
return f"{self.key_prefix}:{game_id}"
async def save(self, game_id:str, game_board:GameBoard) -> None:
redis = await self._get_redis()
payload = pickle.dumps(game_board, protocol=pickle.HIGHEST_PROTOCOL)
await redis.set(self._key(game_id), payload, ex=self.ttl_seconds)
async def load(self, game_id:str):
redis = await self._get_redis()
payload = await redis.get(self._key(game_id))
if payload is None:
return None
return pickle.loads(payload)
async def delete(self, game_id:str) -> None:
redis = await self._get_redis()
await redis.delete(self._key(game_id))
async def close(self) -> None:
if self._redis is None:
return
if hasattr(self._redis, "aclose"):
await self._redis.aclose()
elif hasattr(self._redis, "close"):
close_result = self._redis.close()
if close_result is not None:
await close_result
self._redis = None