gpt4 book ai didi

去优雅关闭负WaitGroup

转载 作者:IT王子 更新时间:2023-10-29 01:59:14 26 4
gpt4 key购买 nike

我已尝试实现 go 服务器的正常关闭,如博文 http://grisha.org/blog/2014/06/03/graceful-restart-in-golang/ 中所述.主要内容如下。

自定义监听器:

var httpWg sync.WaitGroup  // initialised in the other part

type gracefulListener struct {
net.Listener
stop chan error
stopped bool
}

func newGracefulListener(l net.Listener) (gl *gracefulListener) {
gl = &gracefulListener{Listener: l, stop: make(chan error)}
go func() {
_ = <-gl.stop
gl.stopped = true
gl.stop <- gl.Listener.Close()
}()
return
}

func (gl *gracefulListener) Accept() (c net.Conn, err error) {
c, err = gl.Listener.Accept()
if err != nil {
return
}

c = gracefulConn{Conn: c} // wrap using our custom connection

httpWg.Add(1) // increase the counter
return
}

func (gl *gracefulListener) Close() error {
if gl.stopped {
return syscall.EINVAL
}
gl.stop <- nil
return <-gl.stop
}

func (gl *gracefulListener) File() *os.File {
tl := gl.Listener.(*net.TCPListener)
fl, _ := tl.File()
return fl
}

自定义连接:

type gracefulConn struct {
net.Conn
}

func (w gracefulConn) Close() error {
httpWg.Done() // <- panics sometimes
return w.Conn.Close()
}

想法是当程序收到 SIGTERM 时,它会停止为新连接提供服务,并等待现有连接的 httpWg.Wait() 完成。这种方法在本地有效,但当我部署它时,有时我会在 httpWg.Done() 行的 gracefulConn.Close() 中收到 panic :

panic: sync: negative WaitGroup counter

panic 不是在我停止服务器时发生的,而是在例行服务期间发生的。怎么可能有更多的 Close() 调用然后 Accept() 调用?还是我遗漏了什么?

附言我尝试将 stopped 属性和互斥量添加到 gracefullConn,因此在 Close 中它会锁定互斥量并检查 stopped 以确保我们只停止一次。但是,我仍然收到同样的 panic 。

最佳答案

Close() 可以被多次调用,因此您肯定需要在 func (w gracefulConn) Close() error 中检查它。

P.S. I have tried to add stopped property and a mutex to gracefullConn, so in Close it locks the mutex and checks stopped to ensure we stop it only once. However, I still received the same panic.

请记住,如果 gracefulConn 作为值而不是引用传递,那么任何互斥锁/标志都不会按预期工作。所以一定要将c = gracefulConn{Conn: c}变成c = &gracefulConn{Conn: c}

关于去优雅关闭负WaitGroup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33413747/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com