PING a quiet IRC listener client before closing it (closes #155)
check / check (push) Waiting to run

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 was merged in pull request #162.
This commit is contained in:
2026-10-20 20:53:00 +02:00
parent e489f3f3d1
commit e3d01454b3
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)
}()
}
}