From d1316a5b7a60e385f0b9b98a5af8cc319514dece Mon Sep 17 00:00:00 2001 From: mleku Date: Thu, 11 Sep 2025 16:29:43 +0100 Subject: [PATCH] Introduce `DefaultWriteTimeout` for WebSocket operations, replace hardcoded timeouts, and upgrade version to `v0.4.1`. --- app/handle-websocket.go | 15 +++++++++++++-- app/listener.go | 9 ++++----- pkg/version/version | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/handle-websocket.go b/app/handle-websocket.go index 73cfd68..2a1427c 100644 --- a/app/handle-websocket.go +++ b/app/handle-websocket.go @@ -20,6 +20,7 @@ const ( DefaultPongWait = 60 * time.Second DefaultPingWait = DefaultPongWait / 2 DefaultReadTimeout = 3 * time.Second // Read timeout to detect stalled connections + DefaultWriteTimeout = 3 * time.Second DefaultMaxMessageSize = 1 * units.Mb // CloseMessage denotes a close control message. The optional message @@ -140,9 +141,15 @@ whitelist: return } if typ == PingMessage { - if err = conn.Write(ctx, PongMessage, msg); chk.E(err) { + // Create a write context with timeout for pong response + writeCtx, writeCancel := context.WithTimeout( + ctx, DefaultWriteTimeout, + ) + if err = conn.Write(writeCtx, PongMessage, msg); chk.E(err) { + writeCancel() return } + writeCancel() continue } log.T.F("received message from %s: %s", remote, string(msg)) @@ -162,9 +169,13 @@ func (s *Server) Pinger( for { select { case <-ticker.C: - if err = conn.Ping(ctx); chk.E(err) { + // Create a write context with timeout for ping operation + pingCtx, pingCancel := context.WithTimeout(ctx, DefaultWriteTimeout) + if err = conn.Ping(pingCtx); chk.E(err) { + pingCancel() return } + pingCancel() case <-ctx.Done(): return } diff --git a/app/listener.go b/app/listener.go index 24c0c38..dfc9b0c 100644 --- a/app/listener.go +++ b/app/listener.go @@ -3,15 +3,12 @@ package app import ( "context" "net/http" - "time" "github.com/coder/websocket" "lol.mleku.dev/chk" "utils.orly/atomic" ) -const WriteTimeout = 10 * time.Second - type Listener struct { *Server conn *websocket.Conn @@ -31,9 +28,11 @@ func (l *Listener) Ctx() context.Context { func (l *Listener) Write(p []byte) (n int, err error) { // Use a separate context with timeout for writes to prevent race conditions // where the main connection context gets cancelled while writing events - writeCtx, cancel := context.WithTimeout(context.Background(), WriteTimeout) + writeCtx, cancel := context.WithTimeout( + context.Background(), DefaultWriteTimeout, + ) defer cancel() - + if err = l.conn.Write(writeCtx, websocket.MessageText, p); chk.E(err) { return } diff --git a/pkg/version/version b/pkg/version/version index 01e994d..be5bf2a 100644 --- a/pkg/version/version +++ b/pkg/version/version @@ -1 +1 @@ -v0.4.0 \ No newline at end of file +v0.4.1 \ No newline at end of file