#382·coai

CollectQuota 在 goroutine 中使用重复使用的 *gin.Context 导致 utils.GetDBFromContext 发生错误/崩溃

作者: krisxia0506创建于 2025年11月14日更新于 2025年11月14日
标签bug

[//]: # (delete the existing spaces in the box, fill in the x) + [x] I have confirmed that there are no similar issues at present. + [x] I have confirmed that I have upgraded to the latest version. + [x] I have fully reviewed the project README and project documentation and have not found a solution. + [x] I understand and am willing to follow up on this issue, assist with testing, and provide feedback. + [x] I will ask questions in a polite and respectful manner, and will not use uncivilized language (the same applies to everyone who posts comments here, and those who do not comply will be blocked). + [x] I understand and acknowledge the above, and understand that the project maintainers have limited resources. Issues that do not follow the rules may be ignored or closed directly. **Description of the issue** In manager/chat_completions.go (around line 249), the code starts asynchronous logic (goroutine) during request processing and passes the original *gin.Context to CollectQuota. Since gin.Context is returned to the sync.Pool and reused in subsequent requests, if the SSE/connection for the original request is closed and the context is recycled, and the goroutine is still running, the subsequent request may reset the context, causing an error or panic in CollectQuota when utils.GetDBFromContext(c) is called. **Steps to reproduce** 1. Trigger the logic in manager/chat_completions.go that calls CollectQuota in a background goroutine in a request that has SSE enabled. 2. Manually disconnect the client connection (SSE disconnect) while the goroutine is still running, causing the gin.Context to be cancelled and recycled to the pool. 3. Then make another request, causing the pool to be reused and the *gin.Context to be reset. 4. The running goroutine continues to use the reused/already reset *gin.Context, and when utils.GetDBFromContext(c) is called, it may read the reset data or cause a panic. **Expected result** Background/asynchronous tasks should not use *gin.Context that may be reused or has been cancelled directly. Instead, the dependencies needed should be extracted and passed in before starting the goroutine, or use c.Copy() (note that cCopy's Request.Context() will still be cancelled), or change the background task to use a separate service-level context.