contextcheck
contextcheck copied to clipboard
False-positive with a graceful shutdown
Simplified example:
// Run runs server until ctx is canceled, then stops it gracefully and exits.
func RunHandler(ctx context.Context) {
s := http.Server{
BaseContext: func(_ net.Listener) context.Context {
return ctx
},
}
go s.ListenAndServe()
<-ctx.Done()
// use new context for cancelation
stopCtx, stopCancel := context.WithTimeout(context.Background(), time.Second)
defer stopCancel()
s.Shutdown(stopCtx)
s.Close()
}
stopCtx can't be inherited from ctx as the later is already canceled.
Maybe this linter can detect that <-ctx.Done() was already called by this point?
The same I faced with. It is more abstract example
package main
import (
"context"
)
func main() {
doSmth(context.Background())
}
func doSmth(ctx context.Context) {
doSmth2(ctx)
// I want to use context.Background() here
ctx2, ctx2Cancel := context.WithCancel(context.Background())
defer ctx2Cancel()
doSmth2(ctx2)
}
func doSmth2(ctx context.Context) {
_ = ctx
}
main.go:17:9: Non-inherited new context, use function like `context.WithXXX` instead (contextcheck)
doSmth2(ctx2)
The issue occurs when context is provided into the function but I want to use another context instance intentionally. For example graceful shutdown should be done with Background context.
And currently there is no way to avoid this error from the linter
this case can write func like this to pass
func NoInheritCancel(_ context.Context) (context.Context,context.CancelFunc) {
return context.WithCancel(context.Background())
}