def battle(loop): bots = find_participants() bot_map = {bot.safe_full_name: bot for bot in bots} logging.info('Starting compilation') # TODO compile async compilation_success = all(bot.compile() for bot in bots) if not compilation_success: # Save errors on bots access.add_all(bots) logging.warning('Compilation failed') return logging.info('Compilation done') logging.info('Starting graph generation') graph = generate_graph(bot_map.keys()) logging.info('Graph generated: %s', ' | '.join(graph)) with tempfile.TemporaryFile('w+') as tmp_logfile: cmd_map = { name: bot.sandboxed_run_cmd for name, bot in bot_map.items() } game = arbiter.Game(cmd_map, graph, MAX_STEPS, tmp_logfile) player_map = game.players.copy() logging.info('Starting match') with Timed() as timings: loop.run_until_complete(game.play_async()) logging.info('Stopping match') winner = game.winner() if winner: winner = bot_map.get(winner.name) logging.info('{} won'.format(winner) if winner else 'Draw') # Save match outcome to database match = Match(winner=winner, start_time=timings.start_time, end_time=timings.end_time) for name, bot in bot_map.items(): warnings = '\n'.join(player_map[name].warnings) participation = MatchParticipation(bot=bot, errors=warnings) match.participations.append(participation) try: # Saves match object, but also adds an ID so we know where to save # the log of the match to. db.add(match) db.commit() # Store the log file to match.log_path tmp_logfile.seek(0) match.save_log(tmp_logfile.read()) except: logging.exception("Database had to do a rollback.") db.rollback() raise
def battle(loop): bots = find_participants() bot_map = {bot.safe_full_name: bot for bot in bots} logging.info('Starting compilation') # TODO compile async compilation_success = all(bot.compile() for bot in bots) if not compilation_success: # Save errors on bots access.add_all(bots) logging.warning('Compilation failed') return logging.info('Compilation done') logging.info('Starting graph generation') graph = generate_graph(bot_map.keys()) logging.info('Graph generated: %s', ' | '.join(graph)) with tempfile.TemporaryFile('w+') as tmp_logfile: cmd_map = {name: bot.sandboxed_run_cmd for name, bot in bot_map.items()} game = arbiter.Game(cmd_map, graph, MAX_STEPS, tmp_logfile) player_map = game.players.copy() logging.info('Starting match') with Timed() as timings: loop.run_until_complete(game.play_async()) logging.info('Stopping match') winner = game.winner() if winner: winner = bot_map.get(winner.name) logging.info('{} won'.format(winner) if winner else 'Draw') # Save match outcome to database match = Match(winner=winner, start_time=timings.start_time, end_time=timings.end_time) for name, bot in bot_map.items(): warnings = '\n'.join(player_map[name].warnings) participation = MatchParticipation(bot=bot, errors=warnings) match.participations.append(participation) try: # Saves match object, but also adds an ID so we know where to save # the log of the match to. db.add(match) db.commit() # Store the log file to match.log_path tmp_logfile.seek(0) match.save_log(tmp_logfile.read()) except: logging.exception("Database had to do a rollback.") db.rollback() raise
def battle_loop(): loop = asyncio.get_event_loop() try: while True: try: battle(loop) sleep(5) except Exception: db.rollback() logging.exception('Ranker encountered a fatal error') # Keep trying after a while sleep(300) except KeyboardInterrupt: logging.info('Stopping ranker') finally: loop.close()