12 Addr string // host:port where the server is listening.
16 listener *net.TCPListener
20 // Start is essentially (*http.Server)ListenAndServe() with two more
21 // features: (1) by the time Start() returns, Addr is changed to the
22 // address:port we ended up listening to -- which makes listening on
23 // ":0" useful in test suites -- and (2) the server can be shut down
24 // without killing the process -- which is useful in test cases, and
25 // makes it possible to shut down gracefully on SIGTERM without
26 // killing active connections.
27 func (srv *Server) Start() error {
28 addr, err := net.ResolveTCPAddr("tcp", srv.Addr)
32 srv.listener, err = net.ListenTCP("tcp", addr)
36 srv.Addr = srv.listener.Addr().String()
38 mutex := &sync.RWMutex{}
39 srv.cond = sync.NewCond(mutex.RLocker())
42 err = srv.Serve(tcpKeepAliveListener{srv.listener})
54 // Close shuts down the server and returns when it has stopped.
55 func (srv *Server) Close() error {
61 // Wait returns when the server has shut down.
62 func (srv *Server) Wait() error {
67 defer srv.cond.L.Unlock()
74 // tcpKeepAliveListener is copied from net/http because not exported.
75 type tcpKeepAliveListener struct {
79 func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
80 tc, err := ln.AcceptTCP()
85 tc.SetKeepAlivePeriod(3 * time.Minute)