1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
16 Addr string // host:port where the server is listening.
20 listener *net.TCPListener
24 // Start is essentially (*http.Server)ListenAndServe() with two more
25 // features: (1) by the time Start() returns, Addr is changed to the
26 // address:port we ended up listening to -- which makes listening on
27 // ":0" useful in test suites -- and (2) the server can be shut down
28 // without killing the process -- which is useful in test cases, and
29 // makes it possible to shut down gracefully on SIGTERM without
30 // killing active connections.
31 func (srv *Server) Start() error {
32 addr, err := net.ResolveTCPAddr("tcp", srv.Addr)
36 srv.listener, err = net.ListenTCP("tcp", addr)
40 srv.Addr = srv.listener.Addr().String()
42 mutex := &sync.RWMutex{}
43 srv.cond = sync.NewCond(mutex.RLocker())
46 err = srv.Serve(tcpKeepAliveListener{srv.listener})
58 // Close shuts down the server and returns when it has stopped.
59 func (srv *Server) Close() error {
65 // Wait returns when the server has shut down.
66 func (srv *Server) Wait() error {
71 defer srv.cond.L.Unlock()
78 // tcpKeepAliveListener is copied from net/http because not exported.
79 type tcpKeepAliveListener struct {
83 func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
84 tc, err := ln.AcceptTCP()
89 tc.SetKeepAlivePeriod(3 * time.Minute)