杜松子酒服务器的优雅停止

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()

而且它会同样有效,而且更有效率。除此之外,您的解决方案看起来干净、清晰且正确。