better start/stop I hope

This commit is contained in:
əlemi 2021-12-28 11:43:11 +01:00
parent f9d16eddf5
commit f89eded601
2 changed files with 16 additions and 20 deletions

View file

@ -153,6 +153,7 @@ class MinecraftClient(CallbacksHolder, Runnable):
await self.start() await self.start()
async def start(self): async def start(self):
await super().start()
if self.started: if self.started:
return return
self._processing = True self._processing = True
@ -168,6 +169,7 @@ class MinecraftClient(CallbacksHolder, Runnable):
self._logger.info("Minecraft client stopped") self._logger.info("Minecraft client stopped")
if not force: if not force:
await self.join_callbacks() await self.join_callbacks()
await super().stop(force)
async def _client_worker(self): async def _client_worker(self):
while self._processing: while self._processing:

View file

@ -1,40 +1,34 @@
import asyncio import asyncio
import logging import logging
from typing import Optional
from signal import signal, SIGINT, SIGTERM, SIGABRT from signal import signal, SIGINT, SIGTERM, SIGABRT
class Runnable: 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): async def start(self):
raise NotImplementedError self._is_running = True
async def stop(self, force:bool=False): async def stop(self, force:bool=False):
raise NotImplementedError self._is_running = False
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)
def run(self): def run(self):
global DONE
global FORCE_QUIT
logging.info("Starting process") logging.info("Starting process")
DONE = asyncio.Event()
FORCE_QUIT = asyncio.Event()
def signal_handler(signum, __): def signal_handler(signum, __):
global DONE
global FORCE_QUIT
if signum == SIGINT: if signum == SIGINT:
if DONE.is_set(): if self._stop_task:
self._stop_task.cancel()
logging.info("Received SIGINT, terminating") logging.info("Received SIGINT, terminating")
FORCE_QUIT.set()
else: else:
logging.info("Received SIGINT, stopping gracefully...") 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) signal(SIGINT, signal_handler)
@ -42,8 +36,8 @@ class Runnable:
async def main(): async def main():
await self.start() await self.start()
await DONE.wait() while self._is_running:
await self._stop_wrapper() await asyncio.sleep(1)
loop.run_until_complete(main()) loop.run_until_complete(main())