async def close(self, force: bool = True) -> None: """Kill the application by shutting all components down.""" if not self._closing_event.is_set(): _LOGGER.debug("bot requested to shutdown [force:%s]", force) self._closing_event.set() if self._closed or not force: return self._closed = True async def handle(name: str, awaitable: typing.Awaitable[typing.Any]) -> None: future = asyncio.ensure_future(awaitable) try: await future except Exception as ex: loop = asyncio.get_running_loop() loop.call_exception_handler({ "message": f"{name} raised an exception during shutdown", "future": future, "exception": ex, }) await self.dispatch(lifetime_events.StoppingEvent(app=self)) _LOGGER.log( ux.TRACE, "StoppingEvent dispatch completed, now beginning termination") calls = [ ("rest", self._rest.close()), ("chunker", self._chunker.close()), ("voice handler", self._voice.close()), *((f"shard {s.id}", s.close()) for s in self._shards.values()), ] for coro in asyncio.as_completed([handle(*pair) for pair in calls]): await coro # Join any shards until they finish await aio.all_of(*(s.join() for s in self._shards.values()), timeout=len(self._shards)) # Clear out shard map self._shards.clear() await self.dispatch(lifetime_events.StoppedEvent(app=self))
def deserialize_stopping_event(self) -> lifetime_events.StoppingEvent: return lifetime_events.StoppingEvent(app=self._app)