Resolve IRC client hostnames off the accept loop (closes #156)
check / check (push) Waiting to run

acceptLoop called newConn, which did the reverse DNS lookup, with its
three-second timeout, before the loop could accept the next
connection, so one client whose address had no answering reverse DNS
held up every other IRC connect. serve now does the lookup at its
start, on the connection's own goroutine, and the accept loop only
accepts.

The server keeps the lookup function in a field, as it does the ping
times, so that a test can give it one that blocks. The new test
checks that a second client registers while the first one's lookup
has not returned.

Model: opus-5-5
This commit was merged in pull request #172.
This commit is contained in:
2026-10-21 03:31:27 +02:00
parent 3822cdaf1d
commit e7e408c93e
4 changed files with 90 additions and 10 deletions
+10 -2
View File
@@ -52,6 +52,10 @@ type Server struct {
// same names, except in tests, which shorten them.
pingInterval time.Duration
pongDeadline time.Duration
// resolveHost is the function of the same name, except in
// tests, which replace it with one that blocks.
resolveHost func(ctx context.Context, addr string) string
}
// New creates a new IRC Server and registers its lifecycle
@@ -75,6 +79,7 @@ func New(
pingInterval: pingInterval,
pongDeadline: pongDeadline,
resolveHost: resolveHost,
}
listenAddr := params.Config.IRCListenAddr
@@ -175,7 +180,7 @@ func (s *Server) acceptLoop(ctx context.Context) {
}
client := newConn(
ctx, tcpConn, s.log,
tcpConn, s.log,
s.database, s.brk, s.cfg, s.svc,
)
@@ -204,7 +209,10 @@ func (s *Server) acceptLoop(ctx context.Context) {
s.mu.Unlock()
}()
client.serve(ctx, s.pingInterval, s.pongDeadline)
client.serve(
ctx, s.resolveHost,
s.pingInterval, s.pongDeadline,
)
}()
}
}