docs and api cleanup
This commit is contained in:
parent
13afde4bc1
commit
7aa612785a
11
grace.go
11
grace.go
@ -64,7 +64,7 @@ func (c conn) Close() error {
|
|||||||
return c.Conn.Close()
|
return c.Conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new listener.
|
// Wraps an existing File listener to provide a graceful Close() process.
|
||||||
func NewListener(l Listener) Listener {
|
func NewListener(l Listener) Listener {
|
||||||
i := &listener{
|
i := &listener{
|
||||||
Listener: l,
|
Listener: l,
|
||||||
@ -124,7 +124,7 @@ func (l *listener) Accept() (net.Conn, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for signals.
|
// Wait for signals to gracefully terminate or restart the process.
|
||||||
func Wait(listeners []Listener) (err error) {
|
func Wait(listeners []Listener) (err error) {
|
||||||
ch := make(chan os.Signal, 2)
|
ch := make(chan os.Signal, 2)
|
||||||
signal.Notify(ch, syscall.SIGTERM, syscall.SIGUSR2)
|
signal.Notify(ch, syscall.SIGTERM, syscall.SIGUSR2)
|
||||||
@ -155,7 +155,7 @@ func Wait(listeners []Listener) (err error) {
|
|||||||
panic("not reached")
|
panic("not reached")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to inherit listeners from environment variables.
|
// Try to inherit listeners from the parent process.
|
||||||
func Inherit() (listeners []Listener, err error) {
|
func Inherit() (listeners []Listener, err error) {
|
||||||
countStr := os.Getenv(envCountKey)
|
countStr := os.Getenv(envCountKey)
|
||||||
if countStr == "" {
|
if countStr == "" {
|
||||||
@ -179,12 +179,13 @@ func Inherit() (listeners []Listener, err error) {
|
|||||||
return
|
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 {
|
func CloseParent() error {
|
||||||
return syscall.Kill(os.Getppid(), syscall.SIGTERM)
|
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) {
|
func Restart(listeners []Listener) (err error) {
|
||||||
if len(listeners) == 0 {
|
if len(listeners) == 0 {
|
||||||
return errors.New("restart must be given listeners.")
|
return errors.New("restart must be given listeners.")
|
||||||
|
@ -19,15 +19,15 @@ type Handler struct {
|
|||||||
Handler http.Handler
|
Handler http.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
type Handlers []Handler
|
type handlersSlice []Handler
|
||||||
|
|
||||||
var (
|
var (
|
||||||
verbose = flag.Bool("gracehttp.log", true, "Enable logging.")
|
verbose = flag.Bool("gracehttp.log", true, "Enable logging.")
|
||||||
ErrUnexpectedListenersCount = errors.New("unexpected listeners count")
|
errListenersCount = errors.New("unexpected listeners count")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Creates new listeners for all the given addresses.
|
// 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))
|
listeners := make([]grace.Listener, len(handlers))
|
||||||
for index, pair := range handlers {
|
for index, pair := range handlers {
|
||||||
addr, err := net.ResolveTCPAddr("tcp", pair.Addr)
|
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.
|
// 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) {
|
if len(handlers) != len(listeners) {
|
||||||
return ErrUnexpectedListenersCount
|
return errListenersCount
|
||||||
}
|
}
|
||||||
errch := make(chan error, len(listeners)+1) // listeners + grace.Wait
|
errch := make(chan error, len(listeners)+1) // listeners + grace.Wait
|
||||||
for i, l := range listeners {
|
for i, l := range listeners {
|
||||||
@ -71,11 +71,11 @@ func (handlers Handlers) serveWait(listeners []grace.Listener) error {
|
|||||||
return <-errch
|
return <-errch
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve will listen on the given address. It will also wait for a
|
// Serve will serve the given pairs of addresses and listeners and
|
||||||
// SIGUSR2 signal and will restart the server passing the active listener
|
// will monitor for signals allowing for graceful termination (SIGTERM)
|
||||||
// to the new process and avoid dropping active connections.
|
// or restart (SIGUSR2).
|
||||||
func Serve(givenHandlers ...Handler) error {
|
func Serve(givenHandlers ...Handler) error {
|
||||||
handlers := Handlers(givenHandlers)
|
handlers := handlersSlice(givenHandlers)
|
||||||
listeners, err := grace.Inherit()
|
listeners, err := grace.Inherit()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = grace.CloseParent()
|
err = grace.CloseParent()
|
||||||
|
15
readme.md
Normal file
15
readme.md
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user