diff --git a/grace.go b/grace.go index 48da639..fd1b0b6 100644 --- a/grace.go +++ b/grace.go @@ -64,7 +64,7 @@ func (c conn) Close() error { return c.Conn.Close() } -// Create a new listener. +// Wraps an existing File listener to provide a graceful Close() process. func NewListener(l Listener) Listener { i := &listener{ Listener: l, @@ -124,7 +124,7 @@ func (l *listener) Accept() (net.Conn, error) { }, nil } -// Wait for signals. +// Wait for signals to gracefully terminate or restart the process. func Wait(listeners []Listener) (err error) { ch := make(chan os.Signal, 2) signal.Notify(ch, syscall.SIGTERM, syscall.SIGUSR2) @@ -155,7 +155,7 @@ func Wait(listeners []Listener) (err error) { panic("not reached") } -// Try to inherit listeners from environment variables. +// Try to inherit listeners from the parent process. func Inherit() (listeners []Listener, err error) { countStr := os.Getenv(envCountKey) if countStr == "" { @@ -179,12 +179,13 @@ func Inherit() (listeners []Listener, err error) { return } -// Start the Close process in the parent. +// Start the Close process in the parent. This does not wait for the +// parent to close and simply sends it the TERM signal. func CloseParent() error { return syscall.Kill(os.Getppid(), syscall.SIGTERM) } -// Restart the process passing it the given listeners. +// Restart the process passing the given listeners to the new process. func Restart(listeners []Listener) (err error) { if len(listeners) == 0 { return errors.New("restart must be given listeners.") diff --git a/gracehttp/http.go b/gracehttp/http.go index ebab2c7..836c4be 100644 --- a/gracehttp/http.go +++ b/gracehttp/http.go @@ -19,15 +19,15 @@ type Handler struct { Handler http.Handler } -type Handlers []Handler +type handlersSlice []Handler var ( - verbose = flag.Bool("gracehttp.log", true, "Enable logging.") - ErrUnexpectedListenersCount = errors.New("unexpected listeners count") + verbose = flag.Bool("gracehttp.log", true, "Enable logging.") + errListenersCount = errors.New("unexpected listeners count") ) // Creates new listeners for all the given addresses. -func (handlers Handlers) newListeners() ([]grace.Listener, error) { +func (handlers handlersSlice) newListeners() ([]grace.Listener, error) { listeners := make([]grace.Listener, len(handlers)) for index, pair := range handlers { addr, err := net.ResolveTCPAddr("tcp", pair.Addr) @@ -45,9 +45,9 @@ func (handlers Handlers) newListeners() ([]grace.Listener, error) { } // Serve on the given listeners and wait for signals. -func (handlers Handlers) serveWait(listeners []grace.Listener) error { +func (handlers handlersSlice) serveWait(listeners []grace.Listener) error { if len(handlers) != len(listeners) { - return ErrUnexpectedListenersCount + return errListenersCount } errch := make(chan error, len(listeners)+1) // listeners + grace.Wait for i, l := range listeners { @@ -71,11 +71,11 @@ func (handlers Handlers) serveWait(listeners []grace.Listener) error { return <-errch } -// Serve will listen on the given address. It will also wait for a -// SIGUSR2 signal and will restart the server passing the active listener -// to the new process and avoid dropping active connections. +// Serve will serve the given pairs of addresses and listeners and +// will monitor for signals allowing for graceful termination (SIGTERM) +// or restart (SIGUSR2). func Serve(givenHandlers ...Handler) error { - handlers := Handlers(givenHandlers) + handlers := handlersSlice(givenHandlers) listeners, err := grace.Inherit() if err == nil { err = grace.CloseParent() diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..bc83fcb --- /dev/null +++ b/readme.md @@ -0,0 +1,15 @@ +go.grace +======== + +Package grace provides a library that makes it easy to build socket +based servers that can be gracefully terminated & restarted (that is, +without dropping any connections). + +Demo HTTP Server with graceful termination and restart: +https://github.com/nshah/go.grace/blob/master/gracedemo/demo.go + +http level graceful termination and restart: +http://go.pkgdoc.org/github.com/nshah/go.grace/gracehttp + +net.Listener level graceful termination and restart: +http://go.pkgdoc.org/github.com/nshah/go.grace