英文:
How to use defer in combination with http.ListenAndServe?
问题
在使用Go语言中的http.ListenAndServe()
时,会导致阻塞的情况,似乎只能通过终止进程来停止应用程序。这似乎会跳过处理我的defer
语句。请参考下面的代码。当我终止应用程序时,数据库没有关闭。如何确保我的defer
语句会被执行?
func main() {
db := NewDB(DBFILENAME)
defer db.Close()
http.HandleFunc("/", handler)
http.ListenAndServe(":80", nil)
}
英文:
When using http.ListenAndServe()
in Go, this results in a blocking situation where the application, apparently, can only be stopped by killing it. This seems to skip processing my defer
statements. Please see the code below. When I kill the application the db is not closed. How can I make sure my defer
statement will be run?
func main() {
db := NewDB(DBFILENAME)
defer db.Close()
http.HandleFunc("/", handler)
http.ListenAndServe(":80", nil)
}
答案1
得分: 3
defer
语句只有在包含它们的函数返回时才会执行。当你终止主函数时,它并没有返回。所以你需要使用信号和通道。
这是一个很好的链接,解释了相同的问题:https://www.socketloop.com/tutorials/golang-intercept-ctrl-c-interrupt-or-kill-signal-and-determine-the-signal-type。
我在我的上一个项目中遇到了同样的问题。我在我的项目wshare中实现了类似的解决方案。
在你的情况下,你可以尝试像这样的代码:
ch := make(chan os.Signal, 3)
signal.Notify(ch, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
go func() {
signalType := <-ch
signal.Stop(ch)
log.Println("Exit command received. Exiting...")
// 在终止之前,这是一个将所有内容刷新到磁盘的好地方
db.Close()
log.Println("Signal type: ", signalType)
os.Exit(0)
}()
英文:
defer
statements get executed only when the function enclosing them returns. Your main function is not returning when you kill it. So you need to use signals and channels.
This is a good link explaining the same https://www.socketloop.com/tutorials/golang-intercept-ctrl-c-interrupt-or-kill-signal-and-determine-the-signal-type .
I faced the same problem with my last project. I implemented a similar solution in my project wshare .
In your case, you can try something like
ch := make(chan os.Signal, 3)
signal.Notify(ch, os.Interrupt,syscall.SIGTERM,syscall.SIGINT)
go func() {
signalType := <-ch
signal.Stop(ch)
log.Println("Exit command received. Exiting...")
// this is a good place to flush everything to disk
// before terminating.
db.Close()
log.Println("Signal type : ", signalType)
os.Exit(0)
}()
答案2
得分: 3
下一个 Go 发布版本 1.8 中的 HTTP 包将会有一个新的 Shutdown 函数,用于优雅地关闭服务器。https://beta.golang.org/pkg/net/http/#Server.Shutdown
我认为 defer 会起作用。
英文:
The HTTP package in the next go release 1.8 will have a new Shutdown function that gracefully shuts down the server . https://beta.golang.org/pkg/net/http/#Server.Shutdown
I suppose that defer will work then.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论