I have viper providing the following values in config.yml & attached the rest of the configs here:
servers:
- projectname: test
directory: D:\playgroud\test
port: 1029
- projectname: test1
directory: D:\playground\test1
port: 1030
Coniguration.go contains
package config
import ()
type Configuration struct {
Servers []ServerConfiguration
}
package main
import (
"config"
"github.com/spf13/viper"
"log"
"net/http"
)
Server.go
package config
type ServerConfiguration struct {
ProjectName string
Directory string
Port string
}
Main.go
func main() {
viper.SetConfigName("config")
viper.AddConfigPath(".")
var configuration config.Configuration
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err)
}
err := viper.Unmarshal(&configuration)
if err != nil {
log.Fatalf("unable to decode into struct, %v", err)
}
counter := 0
finish := make(chan bool)
for _, h := range configuration.Servers {
counter = counter +1
log.Println(counter)
counter := http.NewServeMux()
counter.HandleFunc("/"+h.ProjectName, foo8001 )
go func() {
http.ListenAndServe(":"+h.Port, counter)
}()
}
<-finish
}
func foo8001(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Listening on 8001: foo "))
}
But when i run the server i only see one serving at 1030 and 1029 seems like the process has ended.
Here is the output:
2018/02/25 03:53:30 1
2018/02/25 03:53:30 2
What am i doing wrong here, Would appreciate any insight to understand it better, Also would appreciate any thought or advice.
Thanks in Advance!
It's probably because your port is changing in loop before it starts the safest way to done it is to pass argument to goroutine and move all of call to h
parameter to goroutine. Something like that should work
for _, h := range configuration.Servers {
counter = counter + 1
log.Println(counter)
go func(h ServerConfiguration) {
server := http.NewServeMux()
server.HandleFunc("/"+h.ProjectName, foo8001)
http.ListenAndServe(":"+h.Port, server)
}(h)
}