From 78da15566351c20b57eff50907844607a06d9a10 Mon Sep 17 00:00:00 2001 From: Roland <33993199+rolznz@users.noreply.github.com> Date: Thu, 13 Nov 2025 19:27:52 +0700 Subject: [PATCH] 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 --- connection.go | 2 +- relay.go | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/connection.go b/connection.go index f6857b2..56ca19d 100644 --- a/connection.go +++ b/connection.go @@ -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) } diff --git a/relay.go b/relay.go index f3d1320..58ecd4c 100644 --- a/relay.go +++ b/relay.go @@ -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