From a27d09f81a60230f686edd648ce2e13f8a11117e Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 21 Nov 2021 02:02:40 +0100 Subject: [PATCH] CommonClient: consolidate shutdown handling --- CommonClient.py | 41 ++++++++++++++++++++++------------------- FactorioClient.py | 9 +-------- SNIClient.py | 23 +++++++---------------- 3 files changed, 30 insertions(+), 43 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index e8a742bba781..2e0b8c5b41fe 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -39,13 +39,13 @@ def _cmd_exit(self) -> bool: def _cmd_connect(self, address: str = "") -> bool: """Connect to a MultiWorld Server""" self.ctx.server_address = None - asyncio.create_task(self.ctx.connect(address if address else None)) + asyncio.create_task(self.ctx.connect(address if address else None), name="connecting") return True def _cmd_disconnect(self) -> bool: """Disconnect from a MultiWorld Server""" self.ctx.server_address = None - asyncio.create_task(self.ctx.disconnect()) + asyncio.create_task(self.ctx.disconnect(), name="disconnecting") return True def _cmd_received(self) -> bool: @@ -89,10 +89,10 @@ def _cmd_ready(self): else: state = ClientStatus.CLIENT_CONNECTED self.output("Unreadied.") - asyncio.create_task(self.ctx.send_msgs([{"cmd": "StatusUpdate", "status": state}])) + asyncio.create_task(self.ctx.send_msgs([{"cmd": "StatusUpdate", "status": state}]), name="send StatusUpdate") def default(self, raw: str): - asyncio.create_task(self.ctx.send_msgs([{"cmd": "Say", "text": raw}])) + asyncio.create_task(self.ctx.send_msgs([{"cmd": "Say", "text": raw}]), name="send Say") class CommonContext(): @@ -149,7 +149,7 @@ def __init__(self, server_address, password): self.set_getters(network_data_package) # execution - self.keep_alive_task = asyncio.create_task(keep_alive(self)) + self.keep_alive_task = asyncio.create_task(keep_alive(self), name="Bouncy") @property def total_locations(self) -> typing.Optional[int]: @@ -236,7 +236,7 @@ async def console_input(self): async def connect(self, address=None): await self.disconnect() - self.server_task = asyncio.create_task(server_loop(self, address)) + self.server_task = asyncio.create_task(server_loop(self, address), name="server loop") def on_print(self, args: dict): logger.info(args["text"]) @@ -282,6 +282,18 @@ async def send_death(self, death_text: str = ""): } }]) + async def shutdown(self): + self.server_address = None + if self.server and not self.server.socket.closed: + await self.server.socket.close() + if self.server_task: + await self.server_task + + while self.input_requests > 0: + self.input_queue.put_nowait(None) + self.input_requests -= 1 + self.keep_alive_task.cancel() + async def keep_alive(ctx: CommonContext, seconds_between_checks=100): """some ISPs/network configurations drop TCP connections if no payload is sent (ignore TCP-keep-alive) @@ -340,14 +352,14 @@ async def server_loop(ctx: CommonContext, address=None): await ctx.connection_closed() if ctx.server_address: logger.info(f"... reconnecting in {ctx.current_reconnect_delay}s") - asyncio.create_task(server_autoreconnect(ctx)) + asyncio.create_task(server_autoreconnect(ctx), name="server auto reconnect") ctx.current_reconnect_delay *= 2 async def server_autoreconnect(ctx: CommonContext): await asyncio.sleep(ctx.current_reconnect_delay) if ctx.server_address and ctx.server_task is None: - ctx.server_task = asyncio.create_task(server_loop(ctx)) + ctx.server_task = asyncio.create_task(server_loop(ctx), name="server loop") async def process_server_cmd(ctx: CommonContext, args: dict): @@ -555,7 +567,7 @@ def on_package(self, cmd: str, args: dict): async def main(args): ctx = TextContext(args.connect, args.password) - ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop") + ctx.server_task = asyncio.create_task(server_loop(ctx), name="server loop") if gui_enabled: input_task = None from kvui import TextManager @@ -566,16 +578,7 @@ async def main(args): ui_task = None await ctx.exit_event.wait() - ctx.server_address = None - if ctx.server and not ctx.server.socket.closed: - await ctx.server.socket.close() - if ctx.server_task: - await ctx.server_task - - while ctx.input_requests > 0: - ctx.input_queue.put_nowait(None) - ctx.input_requests -= 1 - + await ctx.shutdown() if ui_task: await ui_task diff --git a/FactorioClient.py b/FactorioClient.py index 1375f73749a2..096189e1ed2f 100644 --- a/FactorioClient.py +++ b/FactorioClient.py @@ -322,14 +322,7 @@ async def main(args): await progression_watcher await factorio_server_task - if ctx.server and not ctx.server.socket.closed: - await ctx.server.socket.close() - if ctx.server_task: - await ctx.server_task - - while ctx.input_requests > 0: - ctx.input_queue.put_nowait(None) - ctx.input_requests -= 1 + await ctx.shutdown() if ui_task: await ui_task diff --git a/SNIClient.py b/SNIClient.py index 1a2512621fb1..a49deae2c18e 100644 --- a/SNIClient.py +++ b/SNIClient.py @@ -73,7 +73,7 @@ def _cmd_snes(self, snes_options: str = "") -> bool: pass self.ctx.snes_reconnect_address = None - asyncio.create_task(snes_connect(self.ctx, snes_address, snes_device_number)) + asyncio.create_task(snes_connect(self.ctx, snes_address, snes_device_number), name="SNES Connect") return True def _cmd_snes_close(self) -> bool: @@ -1113,28 +1113,19 @@ async def main(): input_task = asyncio.create_task(console_loop(ctx), name="Input") ui_task = None - snes_connect_task = asyncio.create_task(snes_connect(ctx, ctx.snes_address)) + snes_connect_task = asyncio.create_task(snes_connect(ctx, ctx.snes_address), name="SNES Connect") watcher_task = asyncio.create_task(game_watcher(ctx), name="GameWatcher") await ctx.exit_event.wait() - if snes_connect_task: - snes_connect_task.cancel() + ctx.server_address = None ctx.snes_reconnect_address = None - - await watcher_task - - if ctx.server and not ctx.server.socket.closed: - await ctx.server.socket.close() - if ctx.server_task: - await ctx.server_task - if ctx.snes_socket is not None and not ctx.snes_socket.closed: await ctx.snes_socket.close() - - while ctx.input_requests > 0: - ctx.input_queue.put_nowait(None) - ctx.input_requests -= 1 + if snes_connect_task: + snes_connect_task.cancel() + await watcher_task + await ctx.shutdown() if ui_task: await ui_task