Fix: pool reconnect (#200)

* fix: bump ping timeout for poor connections

* fix: always close relay on ping failure

* fix: add multiple ping attempts before closing relay connection

* fix: only 3 ping attempts

* fix: pool check for relay context done

* fix: include relay URL in debug log

* fix: do not return after closing relay on max ping attempts

* fix: compile error
This commit is contained in:
Roland
2025-11-13 19:27:52 +07:00
committed by GitHub
parent fff8322697
commit 78da155663
2 changed files with 18 additions and 6 deletions

View File

@@ -59,7 +59,7 @@ func (c *Connection) Close() error {
// Ping sends a ping message to the websocket connection.
func (c *Connection) Ping(ctx context.Context) error {
ctx, cancel := context.WithTimeoutCause(ctx, time.Millisecond*800, errors.New("ping took too long"))
ctx, cancel := context.WithTimeoutCause(ctx, time.Millisecond*10000, errors.New("ping took too long"))
defer cancel()
return c.conn.Ping(ctx)
}

View File

@@ -9,7 +9,6 @@ import (
"log"
"net/http"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
@@ -168,6 +167,7 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error
// queue all write operations here so we don't do mutex spaghetti
go func() {
pingAttempt := 0
for {
select {
case <-r.connectionContext.Done():
@@ -180,12 +180,24 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error
return
case <-ticker.C:
debugLogf("{%s} pinging relay", r.URL)
err := r.Connection.Ping(r.connectionContext)
if err != nil && !strings.Contains(err.Error(), "failed to wait for pong") {
InfoLogger.Printf("{%s} error writing ping: %v; closing websocket", r.URL, err)
r.Close() // this should trigger a context cancelation
return
if err != nil {
pingAttempt++
debugLogf("{%s} error writing ping (attempt %d): %v", r.URL, pingAttempt, err)
if pingAttempt >= 3 {
debugLogf("{%s} error writing ping after multiple attempts; closing websocket", r.URL)
err = r.Close() // this should trigger a context cancelation
if err != nil {
debugLogf("{%s} failed to close relay: %v", r.URL, err)
}
}
continue
}
// ping was OK
debugLogf("{%s} ping OK", r.URL)
pingAttempt = 0
case writeRequest := <-r.writeQueue:
// all write requests will go through this to prevent races