Retry on temporary net.Listener failure
Instead of stopping to listen, retry on temporary failure. This can happen when running out of FDs. Closes: https://todo.sr.ht/~emersion/soju/183
This commit is contained in:
parent
950198a2b7
commit
69e9b6a439
2
ident.go
2
ident.go
@ -74,6 +74,8 @@ func (s *Identd) Delete(remoteAddr, localAddr string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Identd) Serve(ln net.Listener) error {
|
func (s *Identd) Serve(ln net.Listener) error {
|
||||||
|
ln = &retryListener{Listener: ln}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
conn, err := ln.Accept()
|
conn, err := ln.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
35
server.go
35
server.go
@ -93,6 +93,36 @@ func (g *int64Gauge) Float64() float64 {
|
|||||||
return float64(g.Value())
|
return float64(g.Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type retryListener struct {
|
||||||
|
net.Listener
|
||||||
|
Logger Logger
|
||||||
|
|
||||||
|
delay time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ln *retryListener) Accept() (net.Conn, error) {
|
||||||
|
for {
|
||||||
|
conn, err := ln.Listener.Accept()
|
||||||
|
if ne, ok := err.(net.Error); ok && ne.Temporary() {
|
||||||
|
if ln.delay == 0 {
|
||||||
|
ln.delay = 5 * time.Millisecond
|
||||||
|
} else {
|
||||||
|
ln.delay *= 2
|
||||||
|
}
|
||||||
|
if max := 1 * time.Second; ln.delay > max {
|
||||||
|
ln.delay = max
|
||||||
|
}
|
||||||
|
if ln.Logger != nil {
|
||||||
|
ln.Logger.Printf("accept error (retrying in %v): %v", ln.delay, err)
|
||||||
|
}
|
||||||
|
time.Sleep(ln.delay)
|
||||||
|
} else {
|
||||||
|
ln.delay = 0
|
||||||
|
return conn, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Hostname string
|
Hostname string
|
||||||
Title string
|
Title string
|
||||||
@ -328,6 +358,11 @@ func (s *Server) handle(ic ircConn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Serve(ln net.Listener) error {
|
func (s *Server) Serve(ln net.Listener) error {
|
||||||
|
ln = &retryListener{
|
||||||
|
Listener: ln,
|
||||||
|
Logger: &prefixLogger{logger: s.Logger, prefix: fmt.Sprintf("listener %v: ", ln.Addr())},
|
||||||
|
}
|
||||||
|
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
s.listeners[ln] = struct{}{}
|
s.listeners[ln] = struct{}{}
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user