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
Should server shutdown after receiving "lifespan.shutdown.failed"? #2308
Comments
the issue and patch seems legit to me, can you submit a PR @peterschutt ? |
Thanks @euri10 - I'll polish up the patch and submit a PR. |
I don't think this is a bug. My interpretation from the spec is that once the Also, this is the same behavior as the other ASGI servers. I think what you want is something like this: import anyio
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.routing import Route
import uvicorn
async def infinite_task():
while True:
await anyio.sleep(1)
print("I am alive!")
async def health(request: Request):
return JSONResponse({"status": "ok"})
app = Starlette(routes=[Route("/health", health)])
async def main():
async with anyio.create_task_group() as tg:
tg.start_soon(infinite_task)
config = uvicorn.Config(app=app, host="0.0.0.0", port=8002)
server = uvicorn.Server(config=config)
await server.serve()
if __name__ == "__main__":
anyio.run(main, backend_options={"use_uvloop": True}) |
Thanks @Kludex - that pattern will work just fine!
Do you feel there is a disconnect between the spec, and how some frameworks advertise lifespan? For example, from starlette's docs (ref):
And from litestar (ref):
And lastly, from a framework perspective, can we do any better than returning the "lifespan.shutdown.failed" message, in the case where an exception is caught within the lifespan? |
I'm not sure.
I don't know. |
@euri10 can we close this please? |
Discussed in #2298
Originally posted by peterschutt April 5, 2024
If the shutdown failure message isn't initiated by the app receiving a "lifespan.shutdown" from uvicorn, then the app continues to run after the "lifespan.shutdown.failure" message is received.
Reproducer:
After the error occurs in the lifespan task, the app continues to serve:
Given that apps like starlette and litestar encourage use of the
lifespan
context for orchestration of things that should have a lifespan equivalent to the application object, then I think it would make sense for the app to stop if something has failed within that lifespan after the app has sent "startup.complete" but before the server has sent "shutdown" to the app.The spec seems to agree:
The text was updated successfully, but these errors were encountered: