Esempio n. 1
0
    async def send(self, message: Message) -> None:
        """
        Awaited by the application to send ASGI `lifespan` events.
        """
        message_type = message["type"]
        self.logger.info("%s:  '%s' event received from application.",
                         self.state, message_type)

        if self.state is LifespanCycleState.CONNECTING:

            if self.lifespan == "on":
                raise LifespanFailure(
                    "Lifespan connection failed during startup and lifespan is 'on'."
                )

            # If a message is sent before the startup event is received by the
            # application, then assume that lifespan is unsupported.
            self.state = LifespanCycleState.UNSUPPORTED
            raise LifespanUnsupported("Lifespan protocol appears unsupported.")

        if message_type not in (
                "lifespan.startup.complete",
                "lifespan.shutdown.complete",
                "lifespan.startup.failed",
                "lifespan.shutdown.failed",
        ):
            self.state = LifespanCycleState.FAILED
            raise UnexpectedMessage(
                f"Unexpected '{message_type}' event received.")

        if self.state is LifespanCycleState.STARTUP:
            if message_type == "lifespan.startup.complete":
                self.startup_event.set()
            elif message_type == "lifespan.startup.failed":
                self.state = LifespanCycleState.FAILED
                self.startup_event.set()
                message = message.get("message", "")
                raise LifespanFailure(f"Lifespan startup failure. {message}")

        elif self.state is LifespanCycleState.SHUTDOWN:
            if message_type == "lifespan.shutdown.complete":
                self.shutdown_event.set()
            elif message_type == "lifespan.shutdown.failed":
                self.state = LifespanCycleState.FAILED
                self.shutdown_event.set()
                message = message.get("message", "")
                raise LifespanFailure(f"Lifespan shutdown failure. {message}")
Esempio n. 2
0
 async def shutdown(self) -> None:
     """
     Pushes the `lifespan` shutdown event to application queue and handles errors.
     """
     self.logger.info("Waiting for application shutdown.")
     await self.app_queue.put({"type": "lifespan.shutdown"})
     await self.shutdown_event.wait()
     if self.state is LifespanCycleState.FAILED:
         raise LifespanFailure(self.exception)
Esempio n. 3
0
    async def send(self, message: Message) -> None:
        if not self.is_supported:
            raise LifespanFailure("Lifespan unsupported.")

        message_type = message["type"]
        if message_type == "lifespan.startup.complete":
            self.startup_event.set()
        elif message_type == "lifespan.shutdown.complete":
            self.shutdown_event.set()
        else:
            raise RuntimeError(
                f"Expected lifespan message type, received: {message_type}")
Esempio n. 4
0
    async def startup(self) -> None:
        """
        Pushes the `lifespan` startup event to application queue and handles errors.
        """
        self.logger.info("Waiting for application startup.")
        await self.app_queue.put({"type": "lifespan.startup"})
        await self.startup_event.wait()
        if self.state is LifespanCycleState.FAILED:
            raise LifespanFailure(self.exception)

        if not self.exception:
            self.logger.info("Application startup complete.")
        else:
            self.logger.info("Application startup failed.")