diff options
| author | cyfraeviolae <cyfraeviolae> | 2024-04-03 03:10:44 -0400 | 
|---|---|---|
| committer | cyfraeviolae <cyfraeviolae> | 2024-04-03 03:10:44 -0400 | 
| commit | 6d7ba58f880be618ade07f8ea080fe8c4bf8a896 (patch) | |
| tree | b1c931051ffcebd2bd9d61d98d6233ffa289bbce /venv/lib/python3.11/site-packages/uvicorn/lifespan | |
| parent | 4f884c9abc32990b4061a1bb6997b4b37e58ea0b (diff) | |
venv
Diffstat (limited to 'venv/lib/python3.11/site-packages/uvicorn/lifespan')
| -rw-r--r-- | venv/lib/python3.11/site-packages/uvicorn/lifespan/__init__.py | 0 | ||||
| -rw-r--r-- | venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/__init__.cpython-311.pyc | bin | 0 -> 200 bytes | |||
| -rw-r--r-- | venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/off.cpython-311.pyc | bin | 0 -> 1155 bytes | |||
| -rw-r--r-- | venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/on.cpython-311.pyc | bin | 0 -> 8386 bytes | |||
| -rw-r--r-- | venv/lib/python3.11/site-packages/uvicorn/lifespan/off.py | 17 | ||||
| -rw-r--r-- | venv/lib/python3.11/site-packages/uvicorn/lifespan/on.py | 137 | 
6 files changed, 154 insertions, 0 deletions
| diff --git a/venv/lib/python3.11/site-packages/uvicorn/lifespan/__init__.py b/venv/lib/python3.11/site-packages/uvicorn/lifespan/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/venv/lib/python3.11/site-packages/uvicorn/lifespan/__init__.py diff --git a/venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/__init__.cpython-311.pycBinary files differ new file mode 100644 index 0000000..4efab48 --- /dev/null +++ b/venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/__init__.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/off.cpython-311.pyc b/venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/off.cpython-311.pycBinary files differ new file mode 100644 index 0000000..ca66309 --- /dev/null +++ b/venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/off.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/on.cpython-311.pyc b/venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/on.cpython-311.pycBinary files differ new file mode 100644 index 0000000..52c3ab4 --- /dev/null +++ b/venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/on.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/uvicorn/lifespan/off.py b/venv/lib/python3.11/site-packages/uvicorn/lifespan/off.py new file mode 100644 index 0000000..74554b1 --- /dev/null +++ b/venv/lib/python3.11/site-packages/uvicorn/lifespan/off.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from typing import Any + +from uvicorn import Config + + +class LifespanOff: +    def __init__(self, config: Config) -> None: +        self.should_exit = False +        self.state: dict[str, Any] = {} + +    async def startup(self) -> None: +        pass + +    async def shutdown(self) -> None: +        pass diff --git a/venv/lib/python3.11/site-packages/uvicorn/lifespan/on.py b/venv/lib/python3.11/site-packages/uvicorn/lifespan/on.py new file mode 100644 index 0000000..09df984 --- /dev/null +++ b/venv/lib/python3.11/site-packages/uvicorn/lifespan/on.py @@ -0,0 +1,137 @@ +from __future__ import annotations + +import asyncio +import logging +from asyncio import Queue +from typing import Any, Union + +from uvicorn import Config +from uvicorn._types import ( +    LifespanScope, +    LifespanShutdownCompleteEvent, +    LifespanShutdownEvent, +    LifespanShutdownFailedEvent, +    LifespanStartupCompleteEvent, +    LifespanStartupEvent, +    LifespanStartupFailedEvent, +) + +LifespanReceiveMessage = Union[LifespanStartupEvent, LifespanShutdownEvent] +LifespanSendMessage = Union[ +    LifespanStartupFailedEvent, +    LifespanShutdownFailedEvent, +    LifespanStartupCompleteEvent, +    LifespanShutdownCompleteEvent, +] + + +STATE_TRANSITION_ERROR = "Got invalid state transition on lifespan protocol." + + +class LifespanOn: +    def __init__(self, config: Config) -> None: +        if not config.loaded: +            config.load() + +        self.config = config +        self.logger = logging.getLogger("uvicorn.error") +        self.startup_event = asyncio.Event() +        self.shutdown_event = asyncio.Event() +        self.receive_queue: Queue[LifespanReceiveMessage] = asyncio.Queue() +        self.error_occured = False +        self.startup_failed = False +        self.shutdown_failed = False +        self.should_exit = False +        self.state: dict[str, Any] = {} + +    async def startup(self) -> None: +        self.logger.info("Waiting for application startup.") + +        loop = asyncio.get_event_loop() +        main_lifespan_task = loop.create_task(self.main())  # noqa: F841 +        # Keep a hard reference to prevent garbage collection +        # See https://github.com/encode/uvicorn/pull/972 +        startup_event: LifespanStartupEvent = {"type": "lifespan.startup"} +        await self.receive_queue.put(startup_event) +        await self.startup_event.wait() + +        if self.startup_failed or (self.error_occured and self.config.lifespan == "on"): +            self.logger.error("Application startup failed. Exiting.") +            self.should_exit = True +        else: +            self.logger.info("Application startup complete.") + +    async def shutdown(self) -> None: +        if self.error_occured: +            return +        self.logger.info("Waiting for application shutdown.") +        shutdown_event: LifespanShutdownEvent = {"type": "lifespan.shutdown"} +        await self.receive_queue.put(shutdown_event) +        await self.shutdown_event.wait() + +        if self.shutdown_failed or (self.error_occured and self.config.lifespan == "on"): +            self.logger.error("Application shutdown failed. Exiting.") +            self.should_exit = True +        else: +            self.logger.info("Application shutdown complete.") + +    async def main(self) -> None: +        try: +            app = self.config.loaded_app +            scope: LifespanScope = { +                "type": "lifespan", +                "asgi": {"version": self.config.asgi_version, "spec_version": "2.0"}, +                "state": self.state, +            } +            await app(scope, self.receive, self.send) +        except BaseException as exc: +            self.asgi = None +            self.error_occured = True +            if self.startup_failed or self.shutdown_failed: +                return +            if self.config.lifespan == "auto": +                msg = "ASGI 'lifespan' protocol appears unsupported." +                self.logger.info(msg) +            else: +                msg = "Exception in 'lifespan' protocol\n" +                self.logger.error(msg, exc_info=exc) +        finally: +            self.startup_event.set() +            self.shutdown_event.set() + +    async def send(self, message: LifespanSendMessage) -> None: +        assert message["type"] in ( +            "lifespan.startup.complete", +            "lifespan.startup.failed", +            "lifespan.shutdown.complete", +            "lifespan.shutdown.failed", +        ) + +        if message["type"] == "lifespan.startup.complete": +            assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR +            assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR +            self.startup_event.set() + +        elif message["type"] == "lifespan.startup.failed": +            assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR +            assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR +            self.startup_event.set() +            self.startup_failed = True +            if message.get("message"): +                self.logger.error(message["message"]) + +        elif message["type"] == "lifespan.shutdown.complete": +            assert self.startup_event.is_set(), STATE_TRANSITION_ERROR +            assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR +            self.shutdown_event.set() + +        elif message["type"] == "lifespan.shutdown.failed": +            assert self.startup_event.is_set(), STATE_TRANSITION_ERROR +            assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR +            self.shutdown_event.set() +            self.shutdown_failed = True +            if message.get("message"): +                self.logger.error(message["message"]) + +    async def receive(self) -> LifespanReceiveMessage: +        return await self.receive_queue.get() | 
