杜松子酒服务器的优雅停止
Graceful stop of gin server
我正在尝试使用传递给我的 class 的父上下文来实现一种优雅地停止我的杜松子酒服务器的干净方法。
这是我当前的代码
有没有更简洁的方法来做到这一点?感觉就像很多样板代码和不必要的,例如使用无限循环完成如此简单的任务。
func (instance *MyListener) Listen(ctx context.Context) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
engine := gin.Default()
engine.POST("/doStuff", func(c *gin.Context) {
instance.doStuff()
c.Status(200)
})
instance.httpSrv = &http.Server {
Addr: ":8080",
Handler: engine,
}
// Initializing the server in a goroutine so that
// it won't block the graceful shutdown handling below
go func() {
if err := instance.httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logging.Log.Error("Could not start listener", zap.Error(err))
}
}()
loop:
for {
select {
case <- ctx.Done():
break loop
default:
time.Sleep(1000)
}
}
ctx, cancel = context.WithTimeout(ctx, 2 * time.Second)
if err := instance.httpSrv.Shutdown(ctx); err != nil {
logging.Log.Error("Server forced to shutdown:", err)
}
return nil
}
这个:
loop:
for {
select {
case <- ctx.Done():
break loop
default:
time.Sleep(1000)
}
}
可以替换为:
<- ctx.Done()
而且它会同样有效,而且更有效率。除此之外,您的解决方案看起来干净、清晰且正确。
我正在尝试使用传递给我的 class 的父上下文来实现一种优雅地停止我的杜松子酒服务器的干净方法。 这是我当前的代码
有没有更简洁的方法来做到这一点?感觉就像很多样板代码和不必要的,例如使用无限循环完成如此简单的任务。
func (instance *MyListener) Listen(ctx context.Context) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
engine := gin.Default()
engine.POST("/doStuff", func(c *gin.Context) {
instance.doStuff()
c.Status(200)
})
instance.httpSrv = &http.Server {
Addr: ":8080",
Handler: engine,
}
// Initializing the server in a goroutine so that
// it won't block the graceful shutdown handling below
go func() {
if err := instance.httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logging.Log.Error("Could not start listener", zap.Error(err))
}
}()
loop:
for {
select {
case <- ctx.Done():
break loop
default:
time.Sleep(1000)
}
}
ctx, cancel = context.WithTimeout(ctx, 2 * time.Second)
if err := instance.httpSrv.Shutdown(ctx); err != nil {
logging.Log.Error("Server forced to shutdown:", err)
}
return nil
}
这个:
loop:
for {
select {
case <- ctx.Done():
break loop
default:
time.Sleep(1000)
}
}
可以替换为:
<- ctx.Done()
而且它会同样有效,而且更有效率。除此之外,您的解决方案看起来干净、清晰且正确。