Как уведомить об успешном запуске HTTP-сервера - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь запустить HTTP-сервер в Go, и при запуске сервера должно быть напечатано сообщение, в случае ошибки должно быть напечатано сообщение об ошибке.

Учитывая следующеекод:

const (
    HTTPServerPort = ":4000"
)

func main() {
    var httpServerError = make(chan error)
    var waitGroup sync.WaitGroup

    setupHTTPHandlers()

    waitGroup.Add(1)
    go func() {
        defer waitGroup.Done()

        httpServerError <- http.ListenAndServe(HTTPServerPort, nil)
    }()

    if <-httpServerError != nil {
        fmt.Println("The Logging API service could not be started.", <-httpServerError)
    } else {
        fmt.Println("Logging API Service running @ http://localhost" + HTTPServerPort)
    }

    waitGroup.Wait()
}

Когда я запускаю приложение, я не вижу ничего напечатанного на консоли, где я хотел бы видеть:

Logging API Service running @ http://localhost:4000

Когда я изменяю порт на неверный, на консоль выводится следующий вывод:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]: main.main() ...app.go:45 +0x107 exit status 2

Может ли кто-нибудь указать мне правильное направление, чтобы я знал, что я делаю неправильно с этой реализацией?

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Проблема в том, что ваш оператор if всегда будет читать с канала httpServerError.Однако единственное время, когда что-то записывается, - это сбой сервера.

Попробуйте оператор select:

select{
case err := <-httpServerError
    fmt.Println("The Logging API service could not be started.", err)
default:
    fmt.Println("Logging API Service running @ http://localhost" + HTTPServerPort
}

Случай default будет запущен, если у канала нетчто-нибудь на нем.

Обратите внимание, что это не читает с канала дважды, как ваш пример.Как только вы прочитаете значение из канала, оно исчезнет.Думайте об этом как об очереди.

0 голосов
/ 16 ноября 2018

Это невозможно сделать, если вы не измените логику в своем коде или не используете Listen и Serve по отдельности.Потому что ListenAndServe является функцией блокировки.Если произойдет что-то неожиданное, он вернет вам ошибку.Если это не так, он будет продолжать блокировать работу сервера.Нет ни одного события, которое запускается при каждом запуске сервера.

Давайте тогда запустим Listen и Serve отдельно.

l, err := net.Listen("tcp", ":8080")
if err != nil {
    // handle error
}

// Signal that server is open for business. 

if err := http.Serve(l, rootHandler); err != nil {
    // handle error
}

См. https://stackoverflow.com/a/44598343/4792552.

PS net.Listen не блокируется, потому что работает в фоновом режиме.Другими словами, он просто порождает сокетное соединение на уровне ОС и возвращает вам его детали / ID.Таким образом, вы используете этот идентификатор для прокси-заказов на этот сокет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...