我的职能如下:
func keepConnUp(n netAddr, w chan<- io.Writer, err chan error) {
addr := fmt.Sprintf("%s:%d", n.Addr, n.Port)
for {
<-err
time.Sleep(reconnectTimer)
conn, _ := net.Dial(n.Network, addr)
w <- conn
}
}目标是在收到来自err chan的错误时重拨连接。但我不想重拨,如果我已经拨号或在一定时间内。然而,我可能会收到很多错误,我不想阻止。
我怎么能这么做?
编辑
到目前为止,我已经实现了以下解决方案:
func keepConnUp(n netAddr, w chan<- io.Writer, err chan error) {
addr := fmt.Sprintf("%s:%d", n.Addr, n.Port)
done := make(chan bool)
isDialing := false
for {
select {
case <-err:
if !isDialing {
isDialing = true
time.AfterFunc(reconnectTimer, func() {
done <- true
})
}
case <-done:
conn, _ := net.Dial(n.Network, addr)
w <- conn
isDialing = false
}
}
}发布于 2021-11-02 08:37:36
也许您可以使用sync.WaitGroup来确保错误后只有一个调用可重拨。
发布于 2021-11-02 12:26:34
type Conn struct {
conn net.Conn
dialing bool
mu sync.Mutex
}
func (c Conn) Dial() {
c.mu.Lock()
if c.dialing {
c.mu.Unlock()
return
}
c.dialing = true
c.mu.Unlock()
time.AfterFunc(reconnectTimer, func() {
c.conn, _ := net.Dial(n.Network, addr)
w <- c.conn
c.dialing = false
})
}现在您可以在go例程中调用Conn.Dial()
发布于 2021-11-02 14:34:33
我已经有一段时间没有使用Go了,但是我尝试使用context.Context和sync.Once来实现它。不过,我让没有对进行测试。
func keepConnUp(n netAddr, w chan<- io.Writer, err chan error) {
addr := fmt.Sprintf("%s:%d", n.Addr, n.Port)
done := make(chan bool)
ctx, cancel := context.WithCancel(context.Background())
cancel() // So that ctx.Err() returns non-nil on the first try
once := sync.Once{}
for {
<-err
if ctx.Err() != nil {
once.Do(func() {
conn, _ := net.Dial(n.Network, addr)
w <- conn
})
once = sync.Once{} // Reset once
ctx = context.WithTimeout(reconnectTimer) // Reset context timeout
}
}
}https://stackoverflow.com/questions/69807356
复制相似问题