首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在错误组中运行多台服务器时出现问题

在错误组中运行多台服务器时出现问题
EN

Stack Overflow用户
提问于 2020-09-17 07:36:14
回答 1查看 298关注 0票数 0

我有一个结构:

代码语言:javascript
复制
type MultiServer struct {
    servers []*http.Server
}

func New(servers ...*http.Server) *MultiServer {
    return &MultiServer{servers: servers}
}

func (m *MultiServer) ListenAndServe() error {
    var g errgroup.Group
    for _, s := range m.servers {
        s := s
        g.Go(s.ListenAndServe)
    }

    return g.Wait()
}

如果其中一个服务器返回错误,我希望ListenAndServe立即返回。因此,我将不正确的端口传递给其中一个服务器:

代码语言:javascript
复制
func TestListenAndServe(t *testing.T) {
    one := makeServer(":8080")
    two := makeServer("::8080") // that is incorrect port
    ms := New(one, two)
    done := make(chan error)
    go func() {
        done <- ms.ListenAndServe()
    }()
    select {
    case err := <-done:
        if err == nil {
            t.Fatal("error expected")
        }
    case <-makeTimeChan(5 * time.Second):
        t.Fatal("timeout")
    }
}

func makeServer(port string) *http.Server {
    serveMux := http.NewServeMux()
    hello := func(w http.ResponseWriter, req *http.Request) {
        fmt.Fprintf(w, "hello\n")
    }
    serveMux.HandleFunc("/hello", hello)
    return &http.Server{
        Addr:         port,
        Handler:      serveMux,
        ReadTimeout:  10 * time.Second,
        WriteTimeout: 10 * time.Second,
    }

}

func makeTimeChan(d time.Duration) <-chan time.Time {
    t := time.NewTimer(d)
    return t.C

}

如果我的MultiServer有不止一台服务器,我就会经常得到“超时”。我假设这与在循环中运行服务器有关,因为如果我用以下内容替换ListenAndServe

代码语言:javascript
复制
func (m *MultiServer) ListenAndServe() error {
    var g errgroup.Group
    for _, s := range m.servers {
        _= s
        g.Go(func(){ return errors.New("")})
    }

    return g.Wait()
}

一切都如期而至。有人能帮我找出我做错了什么吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-17 08:25:43

假设您使用的是http.ListenAndServegolang.org/x/sync/errgroup

当所有函数都返回时,

  • 将返回一个returned的Wait
  • 这个returned的Go调用调用给定的函数,如果该函数返回一个错误,则在该组的上下文中调用cancel函数。但是,如果您没有调用WithContext来创建一个具有上下文的组,那么您有一个没有上下文的组,所以不会发生cancel()。

您的eg.Wait()调用等待两个ListenAndServe调用返回。如果您有一个取消函数,并使用它来停止其他ListenAndServe调用,这将有所帮助。见How to stop http.ListenAndServe()。但是,您还需要一个WithContext,这样就可以知道何时停止其他ListenAndServe调用。请注意,一旦您有超过两个这样的功能,您将希望停止所有其他的操作,而不仅仅是(单数)其他。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63933322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档