INNER CODE UNIT · Python
_lifespan
feder-cr/Jobs_Applier_AI_Agent_AIHawk · src/aihawk/mcp/server.py:49
async def _lifespan(_server):
"""Closes every browser on the way out, but only over stdio.
Over streamable HTTP the SDK enters this per MCP session, which is per
CLIENT, not once per process. Measured: with a client attached the machine
had 7 firefox processes, and one second after that client disconnected it
had 1 again. Closing here would therefore kill the browser every time
somebody detached, which is the exact behaviour the registry exists to
remove; there the close stays at process exit, below.
Over stdio `Server.run` enters this exactly once, and its exit is the last
moment the event loop that opened the browsers is still running. That is
the moment to close them: the atexit hook below runs in a NEW loop, and a
Playwright object closed from a loop other than its own never answers.
Measured on Linux, 2026-09-06: a client that closed stdin with a page open
waited 180 s for the process and gave up; with no page it took 0.2 s.
"""
try: