okay
okay

Reputation: 169

How to stop background tasks in a graceful shutdown of FastAPI

Whenever I gracefully shut down my FastAPI app by saving a file (with the --reload option), it waits for all background tasks to be complete before initiating shutdown.

uvicorn INFO:     Shutting down
uvicorn INFO:     connection closed
uvicorn INFO:     Waiting for background tasks to complete. (CTRL+C to force quit)

The problem is that my tasks will never be completed since I need to manually cancel them upon FastAPI shutdown. In the following example:

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Startup logic (if any)
    yield
    logger.info("Shutting down sessions")
    # Shutdown logic (if any)
    Session.close_all()

"Shutting down sessions" is never logged because it is waiting for all background tasks to be completed, which will never happen until I call Session.close_all(). How am I supposed to close my sessions so that FastAPI can properly shut down?

Upvotes: 1

Views: 460

Answers (1)

BSimjoo
BSimjoo

Reputation: 174

Referring to Corky's answer here

You can patch Starlette's exit handler to customize its behavior. Since I am using FastAPI with multiple files I came up with this solution:

from uvicorn.main import Server
from fastapi import FastAPI
....

app = FastAPI()
app.should_exit = False
original_handler = Server.handle_exit

def handle_exit(*args, **kwargs):
    app.should_exit = True
    original_handler(*args, **kwargs)

Server.handle_exit = handle_exit

Additionally, as you mentioned, you can call Session.close_all() inside the handle_exit function.

Upvotes: 1

Related Questions