diff --git a/aiocraft/client.py b/aiocraft/client.py index 16cf202..c509357 100644 --- a/aiocraft/client.py +++ b/aiocraft/client.py @@ -153,6 +153,7 @@ class MinecraftClient(CallbacksHolder, Runnable): await self.start() async def start(self): + await super().start() if self.started: return self._processing = True @@ -168,6 +169,7 @@ class MinecraftClient(CallbacksHolder, Runnable): self._logger.info("Minecraft client stopped") if not force: await self.join_callbacks() + await super().stop(force) async def _client_worker(self): while self._processing: diff --git a/aiocraft/traits/runnable.py b/aiocraft/traits/runnable.py index 2e22a38..eee0d29 100644 --- a/aiocraft/traits/runnable.py +++ b/aiocraft/traits/runnable.py @@ -1,40 +1,34 @@ import asyncio import logging +from typing import Optional from signal import signal, SIGINT, SIGTERM, SIGABRT class Runnable: + _is_running : bool + _stop_task : Optional[asyncio.Task] + + def __init__(self): + self._is_running = False + self._stop_task = None async def start(self): - raise NotImplementedError + self._is_running = True async def stop(self, force:bool=False): - raise NotImplementedError - - async def _stop_wrapper(self): - done, pending = await asyncio.wait((self.stop(), FORCE_QUIT.wait()), return_when=asyncio.FIRST_COMPLETED) - if FORCE_QUIT.is_set(): # means previous stop() didn't finish and user sent another SIGINT - await self.stop(force=True) + self._is_running = False def run(self): - global DONE - global FORCE_QUIT - logging.info("Starting process") - DONE = asyncio.Event() - FORCE_QUIT = asyncio.Event() - def signal_handler(signum, __): - global DONE - global FORCE_QUIT if signum == SIGINT: - if DONE.is_set(): + if self._stop_task: + self._stop_task.cancel() logging.info("Received SIGINT, terminating") - FORCE_QUIT.set() else: logging.info("Received SIGINT, stopping gracefully...") - DONE.set() + self._stop_task = asyncio.get_event_loop().create_task(self.stop(force=self._stop_task is not None)) signal(SIGINT, signal_handler) @@ -42,8 +36,8 @@ class Runnable: async def main(): await self.start() - await DONE.wait() - await self._stop_wrapper() + while self._is_running: + await asyncio.sleep(1) loop.run_until_complete(main())