Контекст.withTimeout() и os.выход в gorilla/mux

# #go #server #gorilla #mux

Вопрос:

Я использую пакет Golang gorilla/mux, и один из примеров выглядит следующим образом:

 func main() {
    var wait time.Duration
    flag.DurationVar(amp;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 := amp;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() вызове (согласно https://gobyexample.com/exit). Я замечаю , что есть CancelFunc() возвращенное сообщение context.WithTimeout() , которое затем откладывается. Я предполагаю, что это должно отменить контекст, созданный выше, если main() он завершится до истечения крайнего срока, но я не вижу, как это может произойти с вызовом os.Exit() в конце. Кто-нибудь может помочь мне понять, чего мне не хватает?

Ответ №1:

Вы правы, функция отложенной отмены никогда не вызывается. Автор, вероятно, хочет указать, что в реальном приложении вы никогда не должны забывать отменять свой контекст.