Changeset 766 in code for trunk/server.go


Ignore:
Timestamp:
Jan 19, 2022, 9:35:46 PM (3 years ago)
Author:
contact
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/server.go

    r756 r766  
    9494}
    9595
     96type retryListener struct {
     97        net.Listener
     98        Logger Logger
     99
     100        delay time.Duration
     101}
     102
     103func (ln *retryListener) Accept() (net.Conn, error) {
     104        for {
     105                conn, err := ln.Listener.Accept()
     106                if ne, ok := err.(net.Error); ok && ne.Temporary() {
     107                        if ln.delay == 0 {
     108                                ln.delay = 5 * time.Millisecond
     109                        } else {
     110                                ln.delay *= 2
     111                        }
     112                        if max := 1 * time.Second; ln.delay > max {
     113                                ln.delay = max
     114                        }
     115                        if ln.Logger != nil {
     116                                ln.Logger.Printf("accept error (retrying in %v): %v", ln.delay, err)
     117                        }
     118                        time.Sleep(ln.delay)
     119                } else {
     120                        ln.delay = 0
     121                        return conn, err
     122                }
     123        }
     124}
     125
    96126type Config struct {
    97127        Hostname        string
     
    329359
    330360func (s *Server) Serve(ln net.Listener) error {
     361        ln = &retryListener{
     362                Listener: ln,
     363                Logger:   &prefixLogger{logger: s.Logger, prefix: fmt.Sprintf("listener %v: ", ln.Addr())},
     364        }
     365
    331366        s.lock.Lock()
    332367        s.listeners[ln] = struct{}{}
Note: See TracChangeset for help on using the changeset viewer.