def __init__(self, worker_manager_class, game_state_generator, django_api_url, port): super(GameRunner, self).__init__() self.worker_manager = worker_manager_class(port=port) self.game_state = game_state_generator(AvatarManager()) self.communicator = DjangoCommunicator(django_api_url=django_api_url, completion_url=django_api_url + 'complete/') self.simulation_runner = ConcurrentSimulationRunner( communicator=self.communicator, game_state=self.game_state) self._end_turn_callback = lambda: None
async def test_get_users_metadata_success(loop, mock_aioresponse): django_api_url = "http://django-api.url" mock_aioresponse.get( f"{django_api_url}users", status=200, payload=DUMMY_GAME_METADATA ) communicator = DjangoCommunicator(django_api_url) response = await communicator.get_game_metadata() assert response == DUMMY_GAME_METADATA
async def test_get_users_500_handled_correctly(loop, mock_aioresponse): django_api_url = "http://django-api.url" mock_aioresponse.get( f"{django_api_url}users", status=500, body="<p>Server error</p>" ) communicator = DjangoCommunicator(django_api_url) with pytest.raises(GameMetadataFetchFailedError): await communicator.get_game_metadata()
def run_game(port, game_id, django_api_url): global cors communicator = DjangoCommunicator(django_api_url=django_api_url) activity_monitor = ActivityMonitor(communicator) app = setup_application(communicator) cors = aiohttp_cors.setup(app) socketio_server = setup_socketIO_server(app) game_runner = create_runner(port, socketio_server, communicator) asyncio.ensure_future(initialize_game_token(communicator, game_id)) game_api = GameAPI( game_state=game_runner.game_state, application=app, socketio_server=socketio_server, activity_monitor=activity_monitor, ) game_runner.set_end_turn_callback(game_api.send_updates_to_all) asyncio.ensure_future(game_runner.run()) future_app.set_result(app)
from aiohttp import web from aiohttp_wsgi import WSGIHandler from authentication import initialize_game_token from prometheus_client import make_wsgi_app from simulation import map_generator from simulation.django_communicator import DjangoCommunicator from simulation.game_runner import GameRunner from simulation.log_collector import LogCollector LOGGER = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) django_api_url = os.environ.get("GAME_API_URL", "http://localhost:8000/kurono/api/games/") communicator = DjangoCommunicator(django_api_url=django_api_url, completion_url=django_api_url + "complete/") activity_monitor = ActivityMonitor(communicator) def setup_application(should_clean_token=True): async def clean_token(app): LOGGER.info("Cleaning token!") await communicator.patch_token(data={"token": ""}) application = web.Application() if should_clean_token: application.on_shutdown.append(clean_token) application.on_shutdown.append(communicator.close_session)
from aiohttp_wsgi import WSGIHandler from authentication import initialize_game_token from prometheus_client import make_wsgi_app from simulation import map_generator from simulation.django_communicator import DjangoCommunicator from simulation.game_runner import GameRunner from simulation.log_collector import LogCollector from turn_collector import TurnCollector LOGGER = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) django_api_url = os.environ.get("GAME_API_URL", "http://localhost:8000/kurono/api/games/") communicator = DjangoCommunicator(django_api_url=django_api_url) activity_monitor = ActivityMonitor(communicator) def setup_application(should_clean_token=True): async def clean_token(app): LOGGER.info("Cleaning token!") await communicator.patch_token(data={"token": ""}) application = web.Application() if should_clean_token: application.on_shutdown.append(clean_token) application.on_shutdown.append(communicator.close_session)
class GameRunner: def __init__( self, game_state_generator, django_api_url, port, worker_manager_class=WorkerManager, ): super(GameRunner, self).__init__() self.worker_manager = worker_manager_class(port=port) self.game_state = game_state_generator(AvatarManager()) self.communicator = DjangoCommunicator( django_api_url=django_api_url, completion_url=django_api_url + "complete/" ) self.simulation_runner = ConcurrentSimulationRunner( communicator=self.communicator, game_state=self.game_state ) self._end_turn_callback = lambda: None def set_end_turn_callback(self, callback_method): self._end_turn_callback = callback_method def get_users_to_add(self, game_metadata): def player_is_new(_player): return _player["id"] not in self.worker_manager.player_id_to_worker.keys() return [ player["id"] for player in game_metadata["users"] if player_is_new(player) ] def get_users_to_delete(self, game_metadata): def player_in_worker_manager_but_not_metadata(pid): return pid not in [player["id"] for player in game_metadata["users"]] return [ player_id for player_id in self.worker_manager.player_id_to_worker.keys() if player_in_worker_manager_but_not_metadata(player_id) ] def update_main_user(self, game_metadata): self.game_state.main_avatar_id = game_metadata["main_avatar"] async def update_workers(self): game_metadata = self.communicator.get_game_metadata()["main"] users_to_add = self.get_users_to_add(game_metadata) users_to_delete = self.get_users_to_delete(game_metadata) await self.worker_manager.add_workers(users_to_add) await self.worker_manager.delete_workers(users_to_delete) self.simulation_runner.add_avatars(users_to_add) self.simulation_runner.delete_avatars(users_to_delete) await self.worker_manager.update_worker_codes(game_metadata["users"]) self.update_main_user(game_metadata) self.worker_manager.fetch_all_worker_data( self.game_state.get_serialized_game_states_for_workers() ) async def update_simulation(self, player_id_to_serialized_actions): await self.simulation_runner.run_single_turn(player_id_to_serialized_actions) await self._end_turn_callback() async def update(self): with GAME_TURN_TIME(): await self.update_workers() await self.update_simulation( self.worker_manager.get_player_id_to_serialized_actions() ) self.worker_manager.clear_logs() self.game_state.turn_count += 1 async def run(self): while True: await self.update()
async def test_get_users_metadata_cannot_connect_to_server(loop, mock_aioresponse): django_api_url = "http://django-api.url" communicator = DjangoCommunicator(django_api_url) with pytest.raises(GameMetadataFetchFailedError): await communicator.get_game_metadata()