我有一个结构:
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()
}一切都如期而至。有人能帮我找出我做错了什么吗?
发布于 2020-09-17 08:25:43
假设您使用的是http.ListenAndServe和golang.org/x/sync/errgroup
当所有函数都返回时,
Wait。Go调用调用给定的函数,如果该函数返回一个错误,则在该组的上下文中调用cancel函数。但是,如果您没有调用WithContext来创建一个具有上下文的组,那么您有一个没有上下文的组,所以不会发生cancel()。您的eg.Wait()调用等待两个ListenAndServe调用返回。如果您有一个取消函数,并使用它来停止其他ListenAndServe调用,这将有所帮助。见How to stop http.ListenAndServe()。但是,您还需要一个WithContext,这样就可以知道何时停止其他ListenAndServe调用。请注意,一旦您有超过两个这样的功能,您将希望停止所有其他的操作,而不仅仅是(单数)其他。
https://stackoverflow.com/questions/63933322
复制相似问题