如何在 FastAPI 关闭时停止循环?

Sir*_*ame 6 python python-asyncio asgi fastapi

我有一条/开始无限循环的路线(从技术上讲,直到 Websocket 断开连接,但在这个简化的示例中,它确实是无限循环)。如何在关机时停止此循环:

from fastapi import FastAPI

import asyncio

app = FastAPI()
running = True

@app.on_event("shutdown")
def shutdown_event():
    global running
    running = False

@app.get("/")
async def index():
    while running:
        await asyncio.sleep(0.1)
Run Code Online (Sandbox Code Playgroud)

根据文档, @app.on_event("shutdown")应该在关闭期间调用,但怀疑它的调用类似于生命周期事件,该事件在一切完成后调用,在这种情况下这是一个死锁。

去测试:

  1. 我运行它作为uvicorn module.filename:app --host 0.0.0.0
  2. 卷曲 http://ip:端口/
  3. 然后停止服务器(按CTRL+C

你会看到它永远挂起,因为 running 永远不会设置为 false,因为shutdown_event没有被调用。(是的,您可以按 强制关机CTRL+C

Sir*_*ame 1

import signal
import asyncio
from fastapi import FastAPI

app = FastAPI()
running = True

def stop_server(*args):
    global running
    running = False

@app.on_event("startup")
def startup_event():
    signal.signal(signal.SIGINT, stop_server)

@app.get("/")
async def index():
    while running:
        await asyncio.sleep(0.1)
Run Code Online (Sandbox Code Playgroud)

来源:https ://github.com/tiangolo/fastapi/discussions/9373#discussioncomment-5573492

设置并捕获SIGINT信号可以捕获第一个信号CNTR+C。这将设置runningFalse循环的结束位置index()。终止正在运行的请求,允许服务器关闭。