-
Notifications
You must be signed in to change notification settings - Fork 1.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
Panics at on context close, v1.33.0 #1205
Comments
I believe it's due to latest |
Are you calling Done() function inside request handler or in some goroutine/task scheulder (ants, etc) where requestctx may be already released? if so, probably Done channel should be copied first into some variable inside request handler or passed to the goroutine as an argument directly. I believe it's the cost of framework reusing requestCtx internally. |
on the init of handler it goes like:
on the defer of the handler there is release context like this:
|
as I understand it logging "context is not released", then panics after 500ms, you still referencing requestCtx inside context.WithTimeout, that's why it panics (handler finishes and sets ctx.s = nil, than somewhere in the context goroutine calling Done and panics). I don't like such behaiviour either. But strange since you are calling cancel, but the problem is here in the context // context.go
go func() {
select {
case <-parent.Done(): // since this goroutine instantiated after the request handler is done, and parent don't have Done (ctx.s already = nil)
child.cancel(false, parent.Err())
case <-child.Done():
}
}() |
I'll make pull request to golang to fix it, I guess it's reasonable) golang/go#50989 |
But in some cases parent.Err() will panic anyway, since server may close s.done channel, and in parallel child cancel then sometimes it might call parent.Err() when s already nil // context.go
go func() {
select {
case <-done: // fixed but
child.cancel(false, parent.Err()) // this is not, any race condition with parent (*requestCtx) can become a problem
case <-child.Done():
}
}() |
I guess it's better to replace done channel inside s to context.Context (*cancelCtx) than no additional goroutine should be created on withTimeout as a result no race condition created for fasthttp.*RequestCtx |
@Gaudeamus you can try this pull request. One of the issues of this pull request is that parent context shared across all requests handlers and all the issues of context.Context behavior... |
Another fix for it is to utilise atomic for requestCtx.s field #1207 (won't fix requestCtx used inside context.Context might receive another server with another done channel concurrently) |
@erikdubbelboer please review, probably you have a better idea how to avoid race condition with RequestCtx. |
just for your info - no warning is triggered, as you assumed
I'm currently downgrating to 1.32, will wait for next release to try. Thanx |
Yes, true, no "context is not released" printed, because the context itself canceled, but context's WithDeadline internal goroutine which relies on (*requestCtx).Done() chan struct will be instantiated afterwards panicing with nil exception on |
I can confirm I'm running into the same issue, when reverting back to |
Sorry I haven't had the time to look into this yet, I will hopefully this weekend. |
Hi, any news about it? |
Can confirm with
|
RequestCtx's are reused in a server specific pool, so no need to reset it. This fixes a use after reset but when RequestCtx is use as context. Fixes #1205
How about this as a fix?: #1234 |
Should totally works as long as context pool server specific! |
RequestCtx's are reused in a server specific pool, so no need to reset it. This fixes a use after reset but when RequestCtx is use as context. Fixes #1205
Hello, unfortunately there are no more details except this message I could find.
The text was updated successfully, but these errors were encountered: