Documentation
¶
Overview ¶
Package Grace provides graceful shutdown made simple for zero to many goroutines.
Tiny library to gracefully shutdown your application by catching the OS signals using [`sync.errgroup`](https://godoc.org/golang.org/x/sync/errgroup).
I often find I have invoked one or more persistent blocking methods, and some other method is needed be invoked in another goroutine to tell it to gracefully shut down when an interrupt is received.
For instance, when ListenAndServe() (https://golang.org/pkg/net/http/#ListenAndServe) is invoked, Shutdown (https://godoc.org/net/http#Server.Shutdown) needs to be called.
This library allows you to start zero or more concurrent goroutines, and trigger a graceful shutdown when an interrupt is received.
• Go net/http package offers Shutdown (https://godoc.org/net/http#Server.Shutdown) function to gracefully shutdown your http server.
• Go database/sql package offers Close(https://godoc.org/database/sql#DB.Close) function to gracefully close the connection to your SQL database.
• Google google.golang.org/grpc package offers Server.GracefulStop` (https://godoc.org/google.golang.org/grpc#Server.GracefulStop), stops accepting new connections, and blocks until all the pending RPCs are finished
Alternatively, this library allows you to invoke zero or more concurrent goroutines with an optional timeout.
Example Usage with ListenAndServe and Shutdown
package main import ( "fmt" "log" "net/http" "time" "github.com/StevenACoffman/grace" ) func main() { wait, ctx := grace.NewWait() var httpServer *http.Server err := wait.WaitWithFunc( func() error { http.HandleFunc("/", healthCheck) httpServer = newHTTPServer() if err := httpServer.ListenAndServe(); err != http.ErrServerClosed { return err } return nil }, func() error { //cleanup: on interrupt, shutdown server <-ctx.Done() log.Printf("closing http goroutine\n") return httpServer.Shutdown(ctx) }) if err != nil { log.Println("finished clean") } else { log.Printf("received error: %v", err) } } func healthCheck(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") w.Header().Set("Content-Length", "0") w.WriteHeader(200) } func newHTTPServer() *http.Server { httpServer := &http.Server{ Addr: fmt.Sprintf(":8080"), ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, } log.Printf("HTTP Metrics server serving at %s", ":8080") return httpServer }
Package grace provides functionality for handling system interrupts.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Wait ¶
type Wait struct {
// contains filtered or unexported fields
}
Wait struct represent wait functionality.
func NewWaitWithContext ¶
NewWaitWithContext - Create a graceful shutdown Wait but provide context
func (*Wait) Wait ¶
Wait - simply wait for interruption.
Example ¶
wait, _ := NewWait() syscall.Kill(os.Getpid(), syscall.SIGTERM) wait.Wait() fmt.Println("Bye")
Output: Bye
func (*Wait) WaitWithFunc ¶
WaitWithFunc receive function(s) as argument and call Wait() to wait interrupt signal. The function(s) will be called before Wait(). Returns the first non-nil error (if any) from the functions.
Example ¶
wait, _ := NewWait() syscall.Kill(os.Getpid(), syscall.SIGTERM) wait.WaitWithFunc(func() error { // your logic here fmt.Println("Bye") return nil })
Output: Bye
func (*Wait) WaitWithTimeout ¶
WaitWithTimeout wait a given amount for time and then exit.
Example ¶
wait, _ := NewWait() syscall.Kill(os.Getpid(), syscall.SIGTERM) wait.WaitWithTimeout(1 * time.Second) fmt.Println("Bye")
Output: Bye
func (*Wait) WaitWithTimeoutAndFunc ¶
WaitWithTimeoutAndFunc call function, wait a given amount of time and then exit. Returns the first non-nil error (if any) from the functions.
Example ¶
wait, _ := NewWait() wait.WaitWithTimeoutAndFunc(1*time.Second, func() error { // your logic here fmt.Println("Bye") return nil })
Output: Bye