[fix] race condition when trying to reconnect (#5547)

This commit is contained in:
Sebastian
2026-10-08 21:22:43 +08:00
committed by GitHub
parent d20a232996
commit d5636108e6
+15 -4
View File
@@ -275,7 +275,15 @@ func (svr *Service) Run(ctx context.Context) error {
} }
func (svr *Service) keepControllerWorking() { func (svr *Service) keepControllerWorking() {
<-svr.ctl.Done() // ctl is swapped under ctlMu in loopLoginUntilSuccess / stop; take a
// snapshot before waiting so stop's nil write does not race this read.
svr.ctlMu.RLock()
ctl := svr.ctl
svr.ctlMu.RUnlock()
if ctl == nil {
return
}
<-ctl.Done()
// There is a situation where the login is successful but due to certain reasons, // There is a situation where the login is successful but due to certain reasons,
// the control immediately exits. It is necessary to limit the frequency of reconnection in this case. // the control immediately exits. It is necessary to limit the frequency of reconnection in this case.
@@ -285,8 +293,11 @@ func (svr *Service) keepControllerWorking() {
// loopLoginUntilSuccess is another layer of loop that will continuously attempt to // loopLoginUntilSuccess is another layer of loop that will continuously attempt to
// login to the server until successful. // login to the server until successful.
svr.loopLoginUntilSuccess(20*time.Second, false) svr.loopLoginUntilSuccess(20*time.Second, false)
if svr.ctl != nil { svr.ctlMu.RLock()
<-svr.ctl.Done() ctl := svr.ctl
svr.ctlMu.RUnlock()
if ctl != nil {
<-ctl.Done()
return false, errors.New("control is closed and try another loop") return false, errors.New("control is closed and try another loop")
} }
// If the control is nil, it means that the login failed and the service is also closed. // If the control is nil, it means that the login failed and the service is also closed.
@@ -377,7 +388,7 @@ func (svr *Service) UpdateAllConfigurer(proxyCfgs []v1.ProxyConfigurer, visitorC
svr.ctlMu.RUnlock() svr.ctlMu.RUnlock()
if ctl != nil { if ctl != nil {
return svr.ctl.UpdateAllConfigurer(proxyCfgs, visitorCfgs) return ctl.UpdateAllConfigurer(proxyCfgs, visitorCfgs)
} }
return nil return nil
} }