使用viper config动态创建的带有net / http的go例程

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)
}