Голанг выполнить функцию после http.ListenAndServe
Я начинаю изучать Голанг, создавая простой http-сервер
func main() {
f, err := os.OpenFile("testlogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
fmt.Println("error opening file: %v", err)
}
defer f.Close()
log.SetOutput(f)
http.HandleFunc("/", defaultHandler)
http.HandleFunc("/check", checkHandler)
serverErr := http.ListenAndServe("127.0.0.1:8080", nil) // set listen port
if serverErr != nil {
log.Println("Error starting server")
} else {
fmt.Println("Started server on - 127.0.0.1:8080" )
}
}
Приведенный выше код запустит локальный сервер на 8080, и я смогу пробиться по маршрутам через браузер. Все хорошо!
Однако теперь я хочу запустить отдельную подпрограмму go, которая просматривает файл -
func initWatch() string{
watcher, err := fsnotify.NewWatcher()
if err != nil {
fmt.Println(err)
}
defer watcher.Close()
done := make(chan bool)
go func() {
for {
select {
case event := <-watcher.Events:
if ( event.Op&fsnotify.Remove == fsnotify.Remove || event.Op&fsnotify.Rename == fsnotify.Rename ) {
fmt.Println("file removed - ", event.Name)
}
case err := <-watcher.Errors:
fmt.Println("error:", err)
}
}
}()
err = watcher.Add("sampledata.txt")
if err != nil {
fmt.Println(err)
}
<-done
}
А теперь, если я вызову функцию initWatch()
ДО http.ListenAndServe("127.0.0.1:8080", nil)
тогда я не могу получить доступ к серверным маршрутам через браузер (ex - localhost:8080), потому что сервер не появился.
Ex -
initWatch()
serverErr := http.ListenAndServe("127.0.0.1:8080", nil) // set listen port
И если я вызову функцию initWatch()
ПОСЛЕ http.ListenAndServe("127.0.0.1:8080", nil)
тогда функция просмотра файлов не работает.
Ex -
serverErr := http.ListenAndServe("127.0.0.1:8080", nil) // set listen port
initWatch()
Как я могу сделать как initWatch()
(наблюдатель файла) и http-сервер работает?
Ценю твою помощь.
2 ответа
Вы можете запустить наблюдателя в отдельной программе. После завершения работы сервера вы отправляете сигнал на выход наблюдателю. лайк:
done := initWatch()
serverErr := http.ListenAndServe("127.0.0.1:8080", nil)
done <- true
Далее немного доработаем наблюдателя - вернем канал, куда нужно уведомить о прекращении работы. Также рабочая программа прослушивает сигнал на выход.
func initWatch() chan bool {
watcher, err := fsnotify.NewWatcher()
if err != nil {
fmt.Println(err)
}
defer watcher.Close()
done := make(chan bool)
go func() {
for {
select {
case event := <-watcher.Events:
if ( event.Op&fsnotify.Remove == fsnotify.Remove || event.Op&fsnotify.Rename == fsnotify.Rename ) {
fmt.Println("file removed - ", event.Name)
}
case err := <-watcher.Errors:
fmt.Println("error:", err)
// listen exit signal
case <- done:
break
}
}
}()
err = watcher.Add("sampledata.txt")
if err != nil {
fmt.Println(err)
}
return done
}
Оба звонка, initWatch()
а также http.ListenAndServe("127.0.0.1:8080", nil)
держи главный горутин в ожидании вечности. initWatch()
ждет значения в <-done
заявление, и никогда не получает один. Ты должен бежать initWatch
или же http.ListenAndServe
в другой горутине, вроде go initWatch()
например. Или, может быть, отправить значение в done
канал из другой программы.