github.com/prebid/prebid-server/v2@v2.18.0/server/listener.go (about)

     1  package server
     2  
     3  import (
     4  	"net"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/golang/glog"
     9  	"github.com/prebid/prebid-server/v2/metrics"
    10  )
    11  
    12  // monitorableListener tracks any opened connections in the metrics.
    13  type monitorableListener struct {
    14  	net.Listener
    15  	metrics metrics.MetricsEngine
    16  }
    17  
    18  // monitorableConnection tracks any closed connections in the metrics.
    19  type monitorableConnection struct {
    20  	net.Conn
    21  	metrics metrics.MetricsEngine
    22  }
    23  
    24  func (l *monitorableConnection) Close() error {
    25  	err := l.Conn.Close()
    26  	if err == nil {
    27  		l.metrics.RecordConnectionClose(true)
    28  	} else {
    29  		// If the connection was closed by the client, it's not a real/actionable error.
    30  		// Although there are no official APIs to detect this, this ridiculous workaround appears
    31  		// in the core Go libs: https://github.com/golang/go/issues/4373#issuecomment-347680321
    32  		errString := err.Error()
    33  		if !strings.Contains(errString, "use of closed network connection") {
    34  			glog.Errorf("Error closing connection: %s", errString)
    35  		}
    36  		l.metrics.RecordConnectionClose(false)
    37  	}
    38  	return err
    39  }
    40  
    41  func (ln *monitorableListener) Accept() (net.Conn, error) {
    42  	tc, err := ln.Listener.Accept()
    43  	if err != nil {
    44  		glog.Errorf("Error accepting connection: %v", err)
    45  		ln.metrics.RecordConnectionAccept(false)
    46  		return tc, err
    47  	}
    48  	ln.metrics.RecordConnectionAccept(true)
    49  	return &monitorableConnection{
    50  		tc,
    51  		ln.metrics,
    52  	}, nil
    53  }
    54  
    55  // tcpKeepAliveListener is copy/pasted from the implementation here: https://golang.org/pkg/net/http/#Server.ListenAndServe
    56  // Since it's not public, the best we can do is copy/paste it here.
    57  //
    58  // We should revisit this after Go 1.11. See also:
    59  // - https://github.com/golang/go/issues/23378
    60  // - https://github.com/golang/go/issues/23459
    61  type tcpKeepAliveListener struct {
    62  	*net.TCPListener
    63  }
    64  
    65  func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
    66  	tc, err := ln.AcceptTCP()
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	tc.SetKeepAlive(true)
    71  	tc.SetKeepAlivePeriod(3 * time.Minute)
    72  	return tc, nil
    73  }
    74  
    75  type unixListener struct{ *net.UnixListener }
    76  
    77  func (ln unixListener) Accept() (net.Conn, error) { return ln.AcceptUnix() }