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()
будет ждать запросов, которые обрабатываются.