Skip to content

Easy graceful shutdowns in your go applications.

License

Notifications You must be signed in to change notification settings

TomWright/grace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Report Card PkgGoDev Test codecov GitHub License GitHub tag (latest by date)

grace

Easy graceful shutdowns in your go applications.

Table of Contents

Usage

First import the module:

go get github.com/tomwright/grace

Quickstart

package main

import (
    "context"
    "github.com/tomwright/grace"
    "time"
)

type myRunner struct {
}

func (mr *myRunner) Run(ctx context.Context) error {
    // Block until we are told to shutdown or until all work is done.
    <-ctx.Done()
    return nil
}

func main() {
    // Initialise grace.
    g := grace.Init(context.Background())

    // The following runners are equivalent.
    runnerA := &myRunner{}
    runnerB := grace.RunnerFunc(func(ctx context.Context) error {
        // Block until we are told to shutdown or until all work is done.
        <-ctx.Done()
        return nil
    })
	
    // Run both runners.
    g.Run(runnerA)
    g.Run(runnerB)

    go func() {
        // Manually shutdown after 2.5 seconds.
        // Alternatively leave this out and rely on os signals to shutdown.
        <-time.After(time.Millisecond * 2500)
        g.Shutdown()
    }()

    // Optionally wait for the shutdown signal to be sent.
    <-g.Context().Done()

    // Wait for all Runners to end.
    g.Wait()
}

Options

Grace allows you to modify the way it is initialised using InitOptions.

g := grace.Init(
  context.Background(),
  grace.InitOptionFn(func(g *grace.Grace) {
    g.LogFn = log.Printf
    g.ErrHandler = func(err error) bool {
    	g.LogFn("something terrible went wrong: %s", err.Error())
    	return true
    }
  })
)

Runners

Grace implements logic to execute and gracefully shutdown any number of Runners.

Each runner must react when the given contexts Done channel is closed.

A runner must implement the Runner interface. It can do this by implementing the Run(context.Context) error func, or by passing a func to RunnerFunc().

Pre-made Runners

Grace doesn't provide any runners in this module in order to reduce forced dependencies... instead please import the required modules below.

Implemented your own runner that you want to share? Raise a PR!

Triggering Shutdowns

Shutdowns can be triggered in a number of ways:

  1. SIGKILL will immediately terminate the application using os.Exit(1).
  2. SIGINT or SIGTERM will trigger a graceful shutdown. Sending 2 or more of these will immediately exit the application using os.Exit(1).
  3. Calling Shutdown() on a grace instance will start a graceful shutdown.
  4. Cancelling the context you gave to grace will start a graceful shutdown.