From 31704891f60adb0106dbcaab39b79d238ac7607f Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Fri, 12 Nov 2021 00:27:15 +0000 Subject: [PATCH] Improve documentation for running complex applications (#6278) (cherry picked from commit 32d715b633c27fbe61ce11bd423e85d0972e1f40) --- CHANGES/6278.doc | 1 + docs/web_advanced.rst | 46 ++++++++++++++++++++++++++++++++++++++++++ docs/web_reference.rst | 10 +++++---- 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 CHANGES/6278.doc diff --git a/CHANGES/6278.doc b/CHANGES/6278.doc new file mode 100644 index 0000000000..2d18217379 --- /dev/null +++ b/CHANGES/6278.doc @@ -0,0 +1 @@ +Added information on running complex applications with additional tasks/processes -- :user:`Dreamsorcerer`. diff --git a/docs/web_advanced.rst b/docs/web_advanced.rst index b2fbe6dcb0..3023f8fe66 100644 --- a/docs/web_advanced.rst +++ b/docs/web_advanced.rst @@ -897,6 +897,52 @@ The task ``listen_to_redis`` will run forever. To shut it down correctly :attr:`Application.on_cleanup` signal handler may be used to send a cancellation to it. +.. _aiohttp-web-complex-applications: + +Complex Applications +^^^^^^^^^^^^^^^^^^^^ + +Sometimes aiohttp is not the sole part of an application and additional +tasks/processes may need to be run alongside the aiohttp :class:`Application`. + +Generally, the best way to achieve this is to use :func:`aiohttp.web.run_app` +as the entry point for the program. Other tasks can then be run via +:attr:`Application.startup` and :attr:`Application.on_cleanup`. By having the +:class:`Application` control the lifecycle of the entire program, the code +will be more robust and ensure that the tasks are started and stopped along +with the application. + +For example, running a long-lived task alongside the :class:`Application` +can be done with a :ref:`aiohttp-web-cleanup-ctx` function like:: + + + async def run_other_task(_app): + task = asyncio.create_task(other_long_task()) + + yield + + task.cancel() + with suppress(asyncio.CancelledError): + await task # Ensure any exceptions etc. are raised. + + app.cleanup_ctx.append(run_other_task) + + +Or a separate process can be run with something like:: + + + async def run_process(_app): + proc = await asyncio.create_subprocess_exec(path) + + yield + + if proc.returncode is None: + proc.terminate() + await proc.wait() + + app.cleanup_ctx.append(run_process) + + Handling error pages -------------------- diff --git a/docs/web_reference.rst b/docs/web_reference.rst index ebe0f430f9..a156f47dbe 100644 --- a/docs/web_reference.rst +++ b/docs/web_reference.rst @@ -2872,13 +2872,15 @@ Utilities reuse_address=None, \ reuse_port=None) - A utility function for running an application, serving it until + A high-level function for running an application, serving it until keyboard interrupt and performing a :ref:`aiohttp-web-graceful-shutdown`. - Suitable as handy tool for scaffolding aiohttp based projects. - Perhaps production config will use more sophisticated runner but it - good enough at least at very beginning stage. + This is a high-level function very similar to :func:`asyncio.run` and + should be used as the main entry point for an application. The + :class:`Application` object essentially becomes our `main()` function. + If additional tasks need to be run in parallel, see + :ref:`aiohttp-web-complex-applications`. The server will listen on any host or Unix domain socket path you supply. If no hosts or paths are supplied, or only a port is supplied, a TCP server