@ -31,6 +31,7 @@ const (
var (
var (
// RWMutex for when adding servers or shutting down
// RWMutex for when adding servers or shutting down
runningServerReg sync . RWMutex
runningServerReg sync . RWMutex
runningServerWG sync . WaitGroup
// ensure we only fork once
// ensure we only fork once
runningServersForked bool
runningServersForked bool
@ -47,6 +48,7 @@ var (
func init ( ) {
func init ( ) {
runningServerReg = sync . RWMutex { }
runningServerReg = sync . RWMutex { }
runningServerWG = sync . WaitGroup { }
DefaultMaxHeaderBytes = 0 // use http.DefaultMaxHeaderBytes - which currently is 1 << 20 (1MB)
DefaultMaxHeaderBytes = 0 // use http.DefaultMaxHeaderBytes - which currently is 1 << 20 (1MB)
}
}
@ -69,6 +71,11 @@ type Server struct {
OnShutdown func ( )
OnShutdown func ( )
}
}
// WaitForServers waits for all running servers to finish
func WaitForServers ( ) {
runningServerWG . Wait ( )
}
// NewServer creates a server on network at provided address
// NewServer creates a server on network at provided address
func NewServer ( network , address string ) * Server {
func NewServer ( network , address string ) * Server {
runningServerReg . Lock ( )
runningServerReg . Lock ( )
@ -110,9 +117,7 @@ func (srv *Server) ListenAndServe(serve ServeFunction) error {
srv . listener = newWrappedListener ( l , srv )
srv . listener = newWrappedListener ( l , srv )
if IsChild {
KillParent ( )
_ = syscall . Kill ( syscall . Getppid ( ) , syscall . SIGTERM )
}
srv . BeforeBegin ( srv . network , srv . address )
srv . BeforeBegin ( srv . network , srv . address )
@ -156,9 +161,7 @@ func (srv *Server) ListenAndServeTLSConfig(tlsConfig *tls.Config, serve ServeFun
wl := newWrappedListener ( l , srv )
wl := newWrappedListener ( l , srv )
srv . listener = tls . NewListener ( wl , tlsConfig )
srv . listener = tls . NewListener ( wl , tlsConfig )
if IsChild {
KillParent ( )
_ = syscall . Kill ( syscall . Getppid ( ) , syscall . SIGTERM )
}
srv . BeforeBegin ( srv . network , srv . address )
srv . BeforeBegin ( srv . network , srv . address )
return srv . Serve ( serve )
return srv . Serve ( serve )
@ -175,10 +178,12 @@ func (srv *Server) ListenAndServeTLSConfig(tlsConfig *tls.Config, serve ServeFun
func ( srv * Server ) Serve ( serve ServeFunction ) error {
func ( srv * Server ) Serve ( serve ServeFunction ) error {
defer log . Debug ( "Serve() returning... (PID: %d)" , syscall . Getpid ( ) )
defer log . Debug ( "Serve() returning... (PID: %d)" , syscall . Getpid ( ) )
srv . setState ( stateRunning )
srv . setState ( stateRunning )
runningServerWG . Add ( 1 )
err := serve ( srv . listener )
err := serve ( srv . listener )
log . Debug ( "Waiting for connections to finish... (PID: %d)" , syscall . Getpid ( ) )
log . Debug ( "Waiting for connections to finish... (PID: %d)" , syscall . Getpid ( ) )
srv . wg . Wait ( )
srv . wg . Wait ( )
srv . setState ( stateTerminate )
srv . setState ( stateTerminate )
runningServerWG . Done ( )
// use of closed means that the listeners are closed - i.e. we should be shutting down - return nil
// use of closed means that the listeners are closed - i.e. we should be shutting down - return nil
if err != nil && strings . Contains ( err . Error ( ) , "use of closed" ) {
if err != nil && strings . Contains ( err . Error ( ) , "use of closed" ) {
return nil
return nil