рутинная работа с net/http, динамически создаваемая с использованием конфигурации viper

У меня есть viper, предоставляющий следующие значения в config.yml и прикрепляющий сюда остальные конфиги:

servers:
  - projectname: test
    directory: D:\playgroud\test
    port: 1029
  - projectname: test1
    directory: D:\playground\test1
    port: 1030

Конфигурация.go содержит

package config

import ()

type Configuration struct {
    Servers []ServerConfiguration
}



package main

    import (
        "config"
        "github.com/spf13/viper"
        "log"
        "net/http"
    )

Сервер.го

package config

type ServerConfiguration struct {
    ProjectName string
    Directory string
    Port string
}

Главная.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 "))
    }

Но когда я запускаю сервер, я вижу только одну подачу на 1030, а 1029 кажется, что процесс закончился.

Вот результат:

2018/02/25 03:53:30 1
2018/02/25 03:53:30 2

Что я здесь делаю неправильно? Буду признателен за любое понимание, чтобы понять это лучше, Также буду признателен за любые мысли или советы.

Заранее спасибо!


person TheeCodeDragon    schedule 25.02.2018    source источник


Ответы (1)


Вероятно, это связано с тем, что ваш порт изменяется в цикле до того, как он запустится. Самый безопасный способ сделать это - передать аргумент горутине и переместить все вызовы параметра h в горутину. Что-то вроде этого должно работать

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)
}
person ttomalak    schedule 25.02.2018