我正在将超时上下文传递给Server.Shutdown(http包)。我看不到我需要调用返回的cancel函数,所以我忽略了它。但是当我跑步时,兽医说the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak
。
如果没有问题,我该如何解决该问题或避免出现go vet错误消息?
go signalShutdown(server, stopCh)
if err := server.ListenAndServeTLS(cert, key); err != http.ErrServerClosed {
log.Fatalf("ListenAndServeTLS() error: %v\n", err)
}
// Note: exit here does not terminate main()
}
// signalShutdown waits for a notification from the OS that the http server
// should be shutdown, then gracefully stops it.
func signalShutdown(server *http.Server, stopCh <-chan struct{}) {
const ForceShutdownAfter = 10 // Shutdown context times out after this many seconds
// Setup chan to receive notification of when server should shut down
quitCh := make(chan os.Signal, 1)
signal.Notify(quitCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
// Wait until we get a notification to stop the server
select {
case <-quitCh:
log.Println("WEB : OS signal received on", server.Addr)
case <-stopCh:
log.Println("WEB : Shutdown message received on", server.Addr)
}
context, _ := context.WithTimeout(context.Background(), ForceShutdownAfter*time.Second)
// Tell the server to shutdown but only after blocking new connections and waiting for the
// existing connections to finish (OR if context expires - see ForceShutdownAfter above)
if err := server.Shutdown(context); err != nil {
log.Fatalf("Shutdown() error: %v", err)
}
os.Exit(0)
}
答案 0 :(得分:2)
...
the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak
。如果没有问题,我该如何解决该问题或避免出现go vet错误消息?
通过调用,而不丢弃as documented函数,this link:
cancel
答案 1 :(得分:-1)
创建上下文对象的方法很少,其中一种是使用context.WithTimeout()
。
通过使用带超时的上下文,我们可以放置一些处理程序,该处理程序将在使用上下文的过程超出定义的超时时触发。看看下面基于您的代码的示例:
context, cancel := context.WithTimeout(context.Background(), ForceShutdownAfter*time.Second)
defer cancel()
chanErr := make(chan error, 1)
go func () {
chanErr <- server.Shutdown(context)
}()
select {
case <-context.Done():
log.Fatalf("Shutdown() timeout")
case chanErr := <-chanErr:
log.Fatalf("Shutdown() error: %v", errMessage)
}
os.Exit(0)
在上面的代码中,我们可以看到context.WithTimeout()
返回两个变量,第二个变量是cancel
,它是一个函数,需要使用defer
关键字进行调用。此外,关闭错误和上下文超时都应谨慎处理。这些是实现上下文超时处理程序的示例。
您的示例中出现警告,因为cancel
被忽略。