fix issue with writing getting caught up under very rare conditions

This commit is contained in:
KingKDot
2026-04-03 20:01:34 -05:00
parent e25834957f
commit 6b4f5f4677
3 changed files with 19 additions and 8 deletions
@@ -9,7 +9,6 @@ import (
)
func HandlePing(ctx context.Context, env *runtime.Env, envelope map[string]interface{}) error {
env.SetLastPong(time.Now().UnixMilli())
ts := extractTimestamp(envelope["ts"])
if ts == 0 {
+1
View File
@@ -589,6 +589,7 @@ func runSession(ctx context.Context, cancel context.CancelFunc, conn *websocket.
last := env.LastPong()
if !last.IsZero() && time.Since(last) > grace {
log.Printf("ping: no pong for %s, forcing reconnect", time.Since(last))
conn.Close(websocket.StatusGoingAway, "pong timeout")
cancel()
return
}
+18 -7
View File
@@ -2,22 +2,33 @@ package wire
import (
"context"
"sync"
"time"
"nhooyr.io/websocket"
)
const writeTimeout = 30 * time.Second
type SafeWriter struct {
mu sync.Mutex
w Writer
sem chan struct{}
w Writer
}
func NewSafeWriter(w Writer) *SafeWriter {
return &SafeWriter{w: w}
sem := make(chan struct{}, 1)
sem <- struct{}{}
return &SafeWriter{sem: sem, w: w}
}
func (s *SafeWriter) Write(ctx context.Context, messageType websocket.MessageType, p []byte) error {
s.mu.Lock()
defer s.mu.Unlock()
return s.w.Write(ctx, messageType, p)
select {
case <-s.sem:
case <-ctx.Done():
return ctx.Err()
}
defer func() { s.sem <- struct{}{} }()
writeCtx, cancel := context.WithTimeout(ctx, writeTimeout)
defer cancel()
return s.w.Write(writeCtx, messageType, p)
}