diff --git a/src/hypercorn/asyncio/__init__.py b/src/hypercorn/asyncio/__init__.py index 3755da0f..0bf625a8 100644 --- a/src/hypercorn/asyncio/__init__.py +++ b/src/hypercorn/asyncio/__init__.py @@ -4,7 +4,7 @@ from typing import Awaitable, Callable, Literal, Optional from .run import worker_serve -from ..config import Config +from ..config import Config, Sockets from ..typing import Framework from ..utils import wrap_app @@ -15,6 +15,7 @@ async def serve( *, shutdown_trigger: Optional[Callable[..., Awaitable]] = None, mode: Optional[Literal["asgi", "wsgi"]] = None, + ready_trigger: Optional[Callable[[Sockets], None]] = None, ) -> None: """Serve an ASGI or WSGI framework app given the config. @@ -34,6 +35,8 @@ async def serve( config: A Hypercorn configuration object. shutdown_trigger: This should return to trigger a graceful shutdown. + ready_trigger: This is called when it is ready to accept + connections. mode: Specify if the app is WSGI or ASGI. """ if config.debug: @@ -42,5 +45,5 @@ async def serve( warnings.warn("The config `workers` has no affect when using serve", Warning) await worker_serve( - wrap_app(app, config.wsgi_max_body_size, mode), config, shutdown_trigger=shutdown_trigger + wrap_app(app, config.wsgi_max_body_size, mode), config, shutdown_trigger=shutdown_trigger, ready_trigger=ready_trigger, ) diff --git a/src/hypercorn/asyncio/run.py b/src/hypercorn/asyncio/run.py index 93bd7fc5..b9346fda 100644 --- a/src/hypercorn/asyncio/run.py +++ b/src/hypercorn/asyncio/run.py @@ -56,6 +56,7 @@ async def worker_serve( *, sockets: Optional[Sockets] = None, shutdown_trigger: Optional[Callable[..., Awaitable]] = None, + ready_trigger: Optional[Callable[[Sockets], None]] = None ) -> None: config.set_statsd_logger_class(StatsdLogger) @@ -77,6 +78,11 @@ def _signal_handler(*_: Any) -> None: # noqa: N803 shutdown_trigger = signal_event.wait + if ready_trigger is None: + def _ready_trigger(sockets: Sockets) -> None: + pass + ready_trigger = _ready_trigger + lifespan_state: LifespanState = {} lifespan = Lifespan(app, config, loop, lifespan_state) @@ -149,6 +155,8 @@ async def _server_callback(reader: asyncio.StreamReader, writer: asyncio.StreamW bind = repr_socket_addr(sock.family, sock.getsockname()) await config.log.info(f"Running on https://{bind} (QUIC) (CTRL + C to quit)") + ready_trigger(sockets) + try: async with TaskGroup() as task_group: task_group.create_task(raise_shutdown(shutdown_trigger))