Skip to content
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.

Commit

Permalink
fix: improve game load time (#1547)
Browse files Browse the repository at this point in the history
* fix: delete only running games in game manager

* get only running games in game_manager

* delete unkown games in game manager

* fix game manager tests

* test list running games

* Merge branch 'development' into razvan-pro/issue1496

* remove remove_stopped_games
  • Loading branch information
razvan-pro committed Jul 2, 2021
1 parent db24b73 commit 172b097
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 21 deletions.
53 changes: 32 additions & 21 deletions aimmo-game-creator/game_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ def remove_unknown_games(self, known_games):
self._remove_game(u)
return unknown_games

def remove_stopped_games(self, stopped_games):
with self._lock:
for s in stopped_games:
self._remove_game(s)
return stopped_games

def get_games(self):
with self._lock:
for g in self._games:
Expand Down Expand Up @@ -98,6 +92,14 @@ def delete_game(self, game_id):

raise NotImplementedError

@abstractmethod
def delete_unknown_games(self):
"""
Deletes the games not present in _data
"""

raise NotImplementedError

def recreate_game(self, game_to_add):
"""Deletes and recreates the given game"""
game_id, game_data = game_to_add
Expand All @@ -119,31 +121,22 @@ def recreate_game(self, game_to_add):
def update(self):
try:
LOGGER.info("Waking up")
games = requests.get(self.games_url).json()
LOGGER.debug(f"Received Games: {games}")
running_games = requests.get(f"{self.games_url}running/").json()
LOGGER.debug(f"Received Running Games: {running_games}")
except (requests.RequestException, ValueError) as ex:
LOGGER.error("Failed to obtain game data")
LOGGER.exception(ex)
else:
games_to_add = {
id: games[id]
for id in self._data.add_new_games(games)
if games[id]["status"] != GameStatus.STOPPED.value
id: running_games[id] for id in self._data.add_new_games(running_games)
}

# Add missing games
self._parallel_map(self.recreate_game, games_to_add.items())
# Delete extra games
known_games = set(games.keys())
stopped_games = set(
id
for id in games.keys()
if games[id]["status"] == GameStatus.STOPPED.value
)
removed_game_ids = self._data.remove_unknown_games(known_games).union(
self._data.remove_stopped_games(stopped_games)
)
self._parallel_map(self.delete_game, removed_game_ids)
running_games_ids = set(running_games.keys())
self._data.remove_unknown_games(running_games_ids)
self.delete_unknown_games()

def get_persistent_state(self, player_id):
"""Get the persistent state of a game"""
Expand Down Expand Up @@ -344,5 +337,23 @@ def delete_game(self, game_id):
self._delete_game_server(game_id)
self._delete_game_secret(game_id)

def delete_unknown_games(self):
gameservers = self.custom_objects_api.list_namespaced_custom_object(
group="agones.dev",
version="v1",
namespace="default",
plural="gameservers",
)
# running games are gameservers that have a game-id label
running_game_ids = set(
gameserver["metadata"]["labels"]["game-id"]
for gameserver in gameservers["items"]
if "metadata" in gameserver
and "labels" in gameserver["metadata"]
and "game-id" in gameserver["metadata"]["labels"]
)
# delete running games that are not known to the game manager
self._parallel_map(self.delete_game, running_game_ids - self._data._games)


GAME_MANAGERS = {"kubernetes": KubernetesGameManager}
3 changes: 3 additions & 0 deletions aimmo-game-creator/tests/test_game_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def delete_game(self, game_id):
except KeyError:
pass

def delete_unknown_games(self):
pass


class RequestMock(object):
def __init__(self, num_games):
Expand Down
36 changes: 36 additions & 0 deletions aimmo/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,3 +520,39 @@ def test_delete_games(self):
assert response.status_code == 204
assert Game.objects.count() == 1
assert Game.objects.get(pk=new_game.id)

def test_list_running_games(self):
self.game.main_user = self.user
self.game.save()

klass3, _, _ = create_class_directly(self.user.email)
klass3.save()
klass4, _, _ = create_class_directly(self.user.email)
klass4.save()

game2 = Game(id=2, name="test", game_class=self.klass2, status=Game.STOPPED)
game2.save()
game3 = Game(id=3, name="test", game_class=klass3, status=Game.RUNNING)
game3.save()
game4 = Game(id=4, name="test", game_class=klass4, status=Game.STOPPED)
game3.save()

def expected_game_detail(class_id, worksheet_id):
return {
"era": "1",
"name": "test",
"status": "r",
"settings": '{"GENERATOR": "Main", "OBSTACLE_RATIO": 0.1, "PICKUP_SPAWN_CHANCE": 0.1, "SCORE_DESPAWN_CHANCE": 0.05, "START_HEIGHT": 31, "START_WIDTH": 31, "TARGET_NUM_CELLS_PER_AVATAR": 16.0, "TARGET_NUM_PICKUPS_PER_AVATAR": 1.2, "TARGET_NUM_SCORE_LOCATIONS_PER_AVATAR": 0.5}',
"class_id": str(class_id),
"worksheet_id": str(worksheet_id),
}

expected_game_list = {
"1": expected_game_detail(self.klass.id, self.worksheet.id),
"3": expected_game_detail(klass3.id, 1),
}

c = Client()
response = c.get(reverse("game-running"))

self.assertJSONEqual(response.content, expected_game_list)
11 changes: 11 additions & 0 deletions aimmo/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,19 @@ def list(self, request):
return Response(response)

@action(
methods=["get"],
detail=False,
)
def running(self, request):
response = {
game.pk: GameSerializer(game).data
for game in Game.objects.filter(status=Game.RUNNING)
}
return Response(response)

@action(
methods=["post"],
detail=False,
serializer_class=GameIdsSerializer,
permission_classes=(CanDeleteGame,),
)
Expand Down

0 comments on commit 172b097

Please sign in to comment.