Skip to content

Commit c4502b0

Browse files
Improve documentation for running complex applications (#6278) (#6299)
(cherry picked from commit 32d715b) Co-authored-by: Sam Bull <[email protected]>
1 parent dcffb53 commit c4502b0

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

CHANGES/6278.doc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added information on running complex applications with additional tasks/processes -- :user:`Dreamsorcerer`.

docs/web_advanced.rst

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,52 @@ The task ``listen_to_redis`` will run forever.
897897
To shut it down correctly :attr:`Application.on_cleanup` signal handler
898898
may be used to send a cancellation to it.
899899

900+
.. _aiohttp-web-complex-applications:
901+
902+
Complex Applications
903+
^^^^^^^^^^^^^^^^^^^^
904+
905+
Sometimes aiohttp is not the sole part of an application and additional
906+
tasks/processes may need to be run alongside the aiohttp :class:`Application`.
907+
908+
Generally, the best way to achieve this is to use :func:`aiohttp.web.run_app`
909+
as the entry point for the program. Other tasks can then be run via
910+
:attr:`Application.startup` and :attr:`Application.on_cleanup`. By having the
911+
:class:`Application` control the lifecycle of the entire program, the code
912+
will be more robust and ensure that the tasks are started and stopped along
913+
with the application.
914+
915+
For example, running a long-lived task alongside the :class:`Application`
916+
can be done with a :ref:`aiohttp-web-cleanup-ctx` function like::
917+
918+
919+
async def run_other_task(_app):
920+
task = asyncio.create_task(other_long_task())
921+
922+
yield
923+
924+
task.cancel()
925+
with suppress(asyncio.CancelledError):
926+
await task # Ensure any exceptions etc. are raised.
927+
928+
app.cleanup_ctx.append(run_other_task)
929+
930+
931+
Or a separate process can be run with something like::
932+
933+
934+
async def run_process(_app):
935+
proc = await asyncio.create_subprocess_exec(path)
936+
937+
yield
938+
939+
if proc.returncode is None:
940+
proc.terminate()
941+
await proc.wait()
942+
943+
app.cleanup_ctx.append(run_process)
944+
945+
900946
Handling error pages
901947
--------------------
902948

docs/web_reference.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2872,13 +2872,15 @@ Utilities
28722872
reuse_address=None, \
28732873
reuse_port=None)
28742874

2875-
A utility function for running an application, serving it until
2875+
A high-level function for running an application, serving it until
28762876
keyboard interrupt and performing a
28772877
:ref:`aiohttp-web-graceful-shutdown`.
28782878

2879-
Suitable as handy tool for scaffolding aiohttp based projects.
2880-
Perhaps production config will use more sophisticated runner but it
2881-
good enough at least at very beginning stage.
2879+
This is a high-level function very similar to :func:`asyncio.run` and
2880+
should be used as the main entry point for an application. The
2881+
:class:`Application` object essentially becomes our `main()` function.
2882+
If additional tasks need to be run in parallel, see
2883+
:ref:`aiohttp-web-complex-applications`.
28822884

28832885
The server will listen on any host or Unix domain socket path you supply.
28842886
If no hosts or paths are supplied, or only a port is supplied, a TCP server

0 commit comments

Comments
 (0)