PING a quiet IRC listener client before closing it (closes #155)
check / check (push) Canceled after 0s

serve closed a connection after five minutes with nothing read and never
sent a PING, so a quiet registered client lost its session. It now sends
PING :<server> after pingInterval with nothing read, and closes the
connection when nothing is read within pongDeadline after that. Every
line read starts both waits again. readTimeout is removed.

Unregistered connections are sent the PING too, so a PONG before
registration is now ignored instead of answered with ERR_NOTREGISTERED.

Model: opus-5-5
This commit is contained in:
clawbot
2026-10-20 18:12:35 +00:00
committed by sneak
parent 164fc93a48
commit 2e399ace90
5 changed files with 247 additions and 7 deletions
+10 -1
View File
@@ -6,6 +6,7 @@ import (
"log/slog"
"net"
"sync"
"time"
"go.uber.org/fx"
"sneak.berlin/go/neoirc/internal/broker"
@@ -38,6 +39,11 @@ type Server struct {
mu sync.Mutex
conns map[*Conn]struct{}
cancel context.CancelFunc
// pingInterval and pongDeadline are the constants of the
// same names, except in tests, which shorten them.
pingInterval time.Duration
pongDeadline time.Duration
}
// New creates a new IRC Server and registers its lifecycle
@@ -57,6 +63,9 @@ func New(
listener: nil,
cancel: nil,
mu: sync.Mutex{},
pingInterval: pingInterval,
pongDeadline: pongDeadline,
}
listenAddr := params.Config.IRCListenAddr
@@ -153,7 +162,7 @@ func (s *Server) acceptLoop(ctx context.Context) {
s.mu.Unlock()
}()
client.serve(ctx)
client.serve(ctx, s.pingInterval, s.pongDeadline)
}()
}
}