Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation for running complex applications #6278

Merged
merged 7 commits into from Nov 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/6278.doc
@@ -0,0 +1 @@
Added information on running complex applications with additional tasks/processes -- :user:`Dreamsorcerer`.
46 changes: 46 additions & 0 deletions docs/web_advanced.rst
Expand Up @@ -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.
Dreamsorcerer marked this conversation as resolved.
Show resolved Hide resolved

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
--------------------

Expand Down
10 changes: 6 additions & 4 deletions docs/web_reference.rst
Expand Up @@ -2784,13 +2784,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
Expand Down