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
104 lines
2.5 KiB
Go
104 lines
2.5 KiB
Go
package ircserver
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"net"
|
|
"time"
|
|
|
|
"sneak.berlin/go/neoirc/internal/broker"
|
|
"sneak.berlin/go/neoirc/internal/config"
|
|
"sneak.berlin/go/neoirc/internal/db"
|
|
"sneak.berlin/go/neoirc/internal/globals"
|
|
"sneak.berlin/go/neoirc/internal/service"
|
|
)
|
|
|
|
// NewTestServer creates a Server suitable for testing, whose
|
|
// connections use interval and deadline in place of
|
|
// pingInterval and pongDeadline.
|
|
// The caller must call Stop() when finished.
|
|
func NewTestServer(
|
|
log *slog.Logger,
|
|
cfg *config.Config,
|
|
database *db.Database,
|
|
brk *broker.Broker,
|
|
interval, deadline time.Duration,
|
|
) *Server {
|
|
globs := &globals.Globals{
|
|
Appname: "neoirc",
|
|
Version: "test",
|
|
StartTime: time.Now(),
|
|
}
|
|
|
|
svc := service.NewTestService(
|
|
database, brk, cfg, globs, log,
|
|
)
|
|
|
|
return &Server{ //nolint:exhaustruct
|
|
log: log,
|
|
cfg: cfg,
|
|
database: database,
|
|
brk: brk,
|
|
svc: svc,
|
|
conns: make(map[*Conn]struct{}),
|
|
|
|
pingInterval: interval,
|
|
pongDeadline: deadline,
|
|
}
|
|
}
|
|
|
|
// Start exposes the unexported start method for tests.
|
|
func (s *Server) Start(addr string) error {
|
|
return s.start(context.Background(), addr)
|
|
}
|
|
|
|
// Stop exposes the unexported stop method for tests.
|
|
func (s *Server) Stop() {
|
|
s.stop()
|
|
}
|
|
|
|
// Listener returns the server's net.Listener for tests.
|
|
func (s *Server) Listener() net.Listener {
|
|
return s.listener
|
|
}
|
|
|
|
// PingTimes returns how long the server's connections wait
|
|
// with nothing read before they are sent a PING, and after it
|
|
// before they are closed.
|
|
func (s *Server) PingTimes() (time.Duration, time.Duration) {
|
|
return s.pingInterval, s.pongDeadline
|
|
}
|
|
|
|
// KillWriteWindow is how long Disconnect allows each write
|
|
// to a killed victim.
|
|
const KillWriteWindow = killWriteWindow
|
|
|
|
// PollInterval is how often the relay checks the client
|
|
// output queue when no broker notification arrives.
|
|
const PollInterval = pollInterval
|
|
|
|
// PingInterval is how long the server waits with nothing read
|
|
// from a connection before it sends a PING.
|
|
const PingInterval = pingInterval
|
|
|
|
// PongDeadline is how long the server waits after the PING
|
|
// for a line before it closes the connection.
|
|
const PongDeadline = pongDeadline
|
|
|
|
// NewTestConn returns a Conn for nick on tcpConn, without a
|
|
// server, database or service behind it.
|
|
func NewTestConn(
|
|
log *slog.Logger,
|
|
cfg *config.Config,
|
|
tcpConn net.Conn,
|
|
nick string,
|
|
) *Conn {
|
|
conn := newConn(
|
|
context.Background(), tcpConn, log,
|
|
nil, nil, cfg, nil,
|
|
)
|
|
conn.nick = nick
|
|
|
|
return conn
|
|
}
|