ethstats: use timer instead of time.Sleep #20924 #21404 (#1442)

* ethstats: use timer instead of time.Sleep #20924

* ethstats: avoid concurrent write on websocket, fixes #21403 #21404
This commit is contained in:
Daniel Liu 2025-09-08 15:37:36 +08:00 committed by GitHub
parent 343cd1021a
commit 3d59a3930f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -261,8 +261,15 @@ func (s *Service) loop() {
if !strings.Contains(path, "://") { if !strings.Contains(path, "://") {
urls = []string{"wss://" + path, "ws://" + path} urls = []string{"wss://" + path, "ws://" + path}
} }
errTimer := time.NewTimer(0)
defer errTimer.Stop()
// Loop reporting until termination // Loop reporting until termination
for { for {
select {
case <-quitCh:
return
case <-errTimer.C:
// Establish a websocket connection to the server on any supported URL // Establish a websocket connection to the server on any supported URL
var ( var (
conn *connWrapper conn *connWrapper
@ -273,22 +280,22 @@ func (s *Service) loop() {
header.Set("origin", "http://localhost") header.Set("origin", "http://localhost")
for _, url := range urls { for _, url := range urls {
c, _, e := dialer.Dial(url, header) c, _, e := dialer.Dial(url, header)
err = e if e == nil {
if err == nil {
conn = newConnectionWrapper(c) conn = newConnectionWrapper(c)
break break
} }
err = e
} }
if err != nil { if err != nil {
log.Warn("Stats server unreachable", "err", err) log.Warn("Stats server unreachable", "err", err)
time.Sleep(10 * time.Second) errTimer.Reset(10 * time.Second)
continue continue
} }
// Authenticate the client with the server // Authenticate the client with the server
if err = s.login(conn); err != nil { if err = s.login(conn); err != nil {
log.Warn("Stats login failed", "err", err) log.Warn("Stats login failed", "err", err)
conn.Close() conn.Close()
time.Sleep(10 * time.Second) errTimer.Reset(10 * time.Second)
continue continue
} }
go s.readLoop(conn) go s.readLoop(conn)
@ -297,11 +304,11 @@ func (s *Service) loop() {
if err = s.report(conn); err != nil { if err = s.report(conn); err != nil {
log.Warn("Initial stats report failed", "err", err) log.Warn("Initial stats report failed", "err", err)
conn.Close() conn.Close()
errTimer.Reset(0)
continue continue
} }
// Keep sending status updates until the connection breaks // Keep sending status updates until the connection breaks
fullReport := time.NewTicker(15 * time.Second) fullReport := time.NewTicker(15 * time.Second)
defer fullReport.Stop()
for err == nil { for err == nil {
select { select {
@ -341,6 +348,7 @@ func (s *Service) loop() {
conn.Close() conn.Close()
} }
} }
}
// readLoop loops as long as the connection is alive and retrieves data packets // readLoop loops as long as the connection is alive and retrieves data packets
// from the network socket. If any of them match an active request, it forwards // from the network socket. If any of them match an active request, it forwards