-
Notifications
You must be signed in to change notification settings - Fork 8k
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
[bug] panic: context: internal error: missing cancel error #1731
Comments
@maopao-691515082 thanks a lot, I will revert the pull request first. can you post one mini example code for testing it? thanks again! |
You sure you didn't just have a bug in your middleware? I hit this issue when I didn't call the cancellation function returned by context.WithTimeout() after calling c.Next(). As long as cancel is called these panics shouldn't occur.
|
I'm sure |
Description
panic in package context:
panic: context: internal error: missing cancel error
goroutine 6 [running]:
context.(*cancelCtx).cancel(0xc000052180, 0xc000090000, 0x0, 0x0)
/home/xiaotao.01/go-1.11/src/context/context.go:369 +0x258
context.(*timerCtx).cancel(0xc000052180, 0x0, 0x0, 0x0)
/home/xiaotao.01/go-1.11/src/context/context.go:447 +0x4a
context.propagateCancel.func1(0xc00007e000, 0x207, 0x10000, 0x4de000, 0xc00000a080, 0x4dde40, 0xc000052180, 0xc0000700c0, 0xc000070120, 0x0)
/home/xiaotao.01/go-1.11/src/context/context.go:281 +0x1f6
created by context.propagateCancel
/home/xiaotao.01/go-1.11/src/context/context.go:271 +0x316
exit status 2
analysis:
gin use sync.pool to cache gin.Context objects:
but a context objects should not be reused, if we use ginCtx as parent to make a new timeout-context(or deadline-context or cancel-context), the package context will start a goroutine to select Done() of parent and child context. if parent is done, cancel child by parent.Err(), but parent is a reusable ginCtx, if it's already using by another handler, the Err() is nil, then panic as above
in short, gin put ginCtx back to pool means "free this context", but it's still used by package context
The Context cannot be cached in the pool, otherwise the Context that is immediately fetched by another goroutine will be in an unknown state, which may lead to a Panic
--by Vincen, my workmate
哎,英文太渣了凑合看吧,用中文大概说一下,就是gin用pool存context是一个错误的做法,因为有可能第一个context在放入pool后立即被另一个go程get出来重用,但这个context还被标准库监听着Done()呢,而且标准库监听的是它之前的Done()返回的chan,这个chan被close(在上面ServeHTTP之后,net/http中)后,标准库要通知它的child,这时候又要调用parent.Err()去获取错误,可惜parent这个被重用了,已经物是人非,Err返回nil,context里面就崩了
老版本没问题是因为老的ginCtx的Done永远返回nil,隐藏了这个问题,最近的新版本改成了用ginCtx.Request.Context(),就不行了,在并发比较高的时候容易触发
The text was updated successfully, but these errors were encountered: