You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastApi退出时卡在等待后台任务完成的问题求助

解决FastAPI+Redis WebSocket退出时的警告与CancelledError问题

问题根源

服务器退出时,WebSocket端点中的while True循环仍在阻塞等待Redis Pub/Sub消息,且未处理asyncio.CancelledError异常,导致后台任务无法正常终止,触发警告和回溯信息。原代码仅捕获了WebSocketDisconnect,未处理服务器关闭时的任务取消信号。

修复方案

1. 添加CancelledError异常捕获

在WebSocket端点的异常处理中加入对asyncio.CancelledError的捕获,确保任务被取消时能妥善清理Redis订阅和WebSocket连接。

2. 优化Redis Pub/Sub消息监听逻辑

改用pubsub.listen()替代get_message(),配合异步迭代器更优雅地处理消息,同时便于响应取消信号。

修改后的WebSocket端点代码

import asyncio
from fastapi import WebSocket, WebSocketDisconnect

@app.websocket("/ws/{user_id}")
async def websocket_endpoint(websocket: WebSocket, user_id: str):
    await manager.connect(websocket)
    channel_name = f"channel_{user_id}"
    async with redis.pubsub() as pubsub:
        await pubsub.subscribe(channel_name)
        try:
            # 使用异步迭代器监听消息,响应取消信号更及时
            async for message in pubsub.listen():
                if message["type"] == "message":
                    decoded_message = message["data"].decode("utf-8")
                    await manager.send_personal_message(decoded_message, websocket)
        except WebSocketDisconnect:
            manager.disconnect(websocket)
        except asyncio.CancelledError:
            # 处理任务取消信号,清理资源
            manager.disconnect(websocket)
            await pubsub.unsubscribe(channel_name)
        finally:
            # 确保无论何种情况都断开连接和取消订阅
            if not websocket.client_state.disconnected:
                manager.disconnect(websocket)
            await pubsub.unsubscribe(channel_name)

额外优化建议

  • 在FastAPI应用中配置关闭事件,主动关闭所有Redis连接,避免资源泄漏:
@app.on_event("shutdown")
async def shutdown_event():
    await redis.close()
    await redis.wait_closed()

原理说明

  • async for message in pubsub.listen()会自动响应异步任务的取消信号,当服务器关闭时,任务被取消会触发CancelledError,此时我们可以在异常处理块中完成资源清理。
  • 新增的finally块确保无论正常退出还是异常退出,都能断开WebSocket连接并取消Redis订阅,避免后台任务残留。

内容的提问来源于stack exchange,提问作者nehat khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:51:10