@@ -897,6 +897,52 @@ The task ``listen_to_redis`` will run forever.
897897To shut it down correctly :attr: `Application.on_cleanup ` signal handler
898898may 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+
900946Handling error pages
901947--------------------
902948
0 commit comments