Golang изящное завершение работы HTTP-сервера с обработкой ошибок

Я нахожусь в процессе получения моего сервера HTTP, чтобы изящно завершить работу. Я воспользовался советами из этого поста и настроил свой код следующим образом:

func start() {

    //......

    //START HTTP/SOCKET LISTENER
    if settings.TLS {
        httpServer = makeServer("/wss", settings.TLS);
    } else {
        httpServer = makeServer("/ws", settings.TLS);
    }

    //...
}

func makeServer(handleDir string, tls bool) (*http.Server) {
    server := &http.Server{Addr: settings.IP+":"+strconv.Itoa(settings.Port)}
    http.HandleFunc(handleDir, socketInitializer)
    if tls {
        go func() {
            err := server.ListenAndServeTLS(settings.CertFile, settings.PrivKeyFile)
            if err != nil {
                serverError(err)
            }
        }()
    }else{
        go func() {
            err := server.ListenAndServe()
            if err != nil {
                serverError(err)
            }
        }()
    }

    //
    return server
}

Итак, у меня есть несколько вопросов о том, как все это работает сейчас:

1) Ответ, который я связал выше, гласит: "ПРИМЕЧАНИЕ: есть вероятность, что следующая строка не успеет..." ListenAndServe() обработка ошибок внутри программы. Как я могу убедиться, что serverError() будет гарантировать завершение? Нужно ли делать какие-то блокировки в этом потоке, или я делаю канал в главном потоке, который он может вызвать?

2) На данный момент, я не уверен, есть ли у меня способ сказать, если я Server.ShutDown() http.Server, или если он выдал ошибку и выключился. Ли ListenAndServe() ошибка выдается даже если я использовал Server.ShutDown() метод? Вот почему принятый ответ в ссылке использует err != http.ErrServerClosed при проверке ListenAndServe() ошибка?

3) start() Функция (конечно) выполняется в основном потоке. Не нужно ли каким-то образом блокировать этот поток, чтобы программа не возвращалась и не выходила или ListenAndServe() позаботиться об этом для меня?

4) После того как я позвоню Server.ShutDown() мне нужно сделать что-нибудь, чтобы закрыть http.HandleFunc() слушатели?

Любая помощь по любой из этих тем будет принята с благодарностью, поэтому не беспокойтесь, если вы не можете затронуть все сразу:)

РЕДАКТИРОВАТЬ: Если кто-то хочет увидеть, как я в конечном итоге заставить все это работать правильно, вы можете посмотреть на этот файл, строка 225 и далее.

1 ответ

Решение

main Функция должна каким-то образом ждать всех подпрограмм go, которые вы хотите полностью выполнить.

Итак, 1) вопрос: вы должны заблокировать основную программу, чтобы убедиться, serverError может быть выполнен

И 3) вопрос: абсолютно вы должны заблокировать на start() или снаружи start() самостоятельно, или программа будет завершена немедленно.

Что касается 2). документ указывает:

ListenAndServe всегда возвращает ненулевую ошибку.

так err != http.ErrServerClosed просто работает для ситуации Server.ShutDown(), Все же есть другие ошибки, которые могут возникнуть.

4) Ничего не делать, чтобы закрыть http.HandleFunc() так как Server.ShutDown() будет ждать запросов, которые обрабатываются.

Другие вопросы по тегам