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