multithreading - 在错误组中运行多个服务器的问题

标签 multithreading go concurrency

我有一个结构:

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将立即返回。
因此,我将错误的端口传递给其中一台服务器:
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替换为:
func (m *MultiServer) ListenAndServe() error {
    var g errgroup.Group
    for _, s := range m.servers {
        _= s
        g.Go(func(){ return errors.New("")})
    }

    return g.Wait()
}
一切都按预期进行。
有人可以帮我弄清楚我在做什么错吗?

最佳答案

假设您正在使用http.ListenAndServegolang.org/x/sync/errgroup:

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

  • 您的eg.Wait()调用等待两个ListenAndServe调用返回。如果您具有取消功能并将其用于停止其他ListenAndServe调用,那将有所帮助。参见How to stop http.ListenAndServe()。但是,您还需要一个WithContext,这样您才能知道何时停止其他ListenAndServe调用。请注意,一旦您拥有多个这样的对象,您将希望停止所有其他对象,而不仅仅是其他对象。

    关于multithreading - 在错误组中运行多个服务器的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63933322/

    相关文章:

    objective-c - 避免复制 NSMutableArray 以使用多线程写入进行读取

    python - 如何避免Django子线程被uWSGI respawn杀死

    SPListItemCollection 上的 C# Parallel.ForEach() 导致异常 (0x80010102)

    pointers - 为什么 http.Client{} 的前缀是 &?

    go - Go sync.pool 比 make 慢很多吗?

    c++ - 多次使用 std::async 对小任务性能友好吗?

    python - 全局解释器锁 : Jython vs CPython

    java:多线程、多用户 Web 应用程序中的 FTP

    go - 'go'工具安装可执行文件后如何访问资源文件?

    java - 能见度保证