如何解决大猩猩/多路复用器中的 Context.WithTimeout() 和 os.exit
我使用的是 Golang gorilla/mux 包,其中一个例子如下:
func main() {
var wait time.Duration
flag.DurationVar(&wait,"graceful-timeout",time.Second * 15,"the duration for which the server gracefully wait for existing connections to finish - e.g. 15s or 1m")
flag.Parse()
r := mux.NewRouter()
// Add your routes as needed
srv := &http.Server{
Addr: "0.0.0.0:8080",// Good practice to set timeouts to avoid Slowloris attacks.
WriteTimeout: time.Second * 15,ReadTimeout: time.Second * 15,IdleTimeout: time.Second * 60,Handler: r,// Pass our instance of gorilla/mux in.
}
// Run our server in a goroutine so that it doesn't block.
go func() {
if err := srv.ListenAndServe(); err != nil {
log.Println(err)
}
}()
c := make(chan os.Signal,1)
// We'll accept graceful shutdowns when quit via SIGINT (Ctrl+C)
// SIGKILL,SIGQUIT or SIGTERM (Ctrl+/) will not be caught.
signal.Notify(c,os.Interrupt)
// Block until we receive our signal.
<-c
// Create a deadline to wait for.
ctx,cancel := context.WithTimeout(context.Background(),wait)
defer cancel()
// Doesn't block if no connections,but will otherwise wait
// until the timeout deadline.
srv.Shutdown(ctx)
// Optionally,you could run srv.Shutdown in a goroutine and block on
// <-ctx.Done() if your application should wait for other services
// to finalize based on context cancellation.
log.Println("shutting down")
os.Exit(0)
}
这看起来很简单,但我的理解是当调用 os.Exit()
时 defers 不会运行(按照 https://gobyexample.com/exit)。我注意到 CancelFunc()
返回了一个 context.WithTimeout()
,然后被推迟。我的猜测是,如果 main()
在截止日期之前完成,这应该取消上面创建的上下文,但我不知道在最后调用 os.Exit()
会发生什么情况。谁能帮我看看我错过了什么?
解决方法
你说得对,延迟取消函数永远不会被调用。作者想大概指出,在实际应用中,永远不要忘记取消上下文。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。