func (f *Finisher) Trigger() {
	f.getManSig() <- nil
}
Trigger the shutdown signal manually. This is probably only useful for testing.
package finish
import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"
)
const DefaultTimeout = 10 * time.Second
var (
	DefaultLogger = &defaultLogger{}
	StdoutLogger = &stdoutLogger{}
	DefaultSignals = []os.Signal{syscall.SIGINT, syscall.SIGTERM}
)
type Server interface {
	Shutdown(ctx context.Context) error
}
type serverKeeper struct {
	srv     Server
	name    string
	timeout time.Duration
}
type Finisher struct {
	Timeout time.Duration
	Log Logger
	Signals []os.Signal
	mutex   sync.Mutex
	keepers []*serverKeeper
	manSig  chan interface{}
}
func New() *Finisher {
	return &Finisher{}
}
func (f *Finisher) signals() []os.Signal {
	if f.Signals != nil {
		return f.Signals
	}
	return DefaultSignals
}
func (f *Finisher) log() Logger {
	if f.Log != nil {
		return f.Log
	}
	return DefaultLogger
}
func (f *Finisher) timeout() time.Duration {
	if f.Timeout != 0 {
		return f.Timeout
	}
	return DefaultTimeout
}
func (f *Finisher) getManSig() chan interface{} {
	f.mutex.Lock()
	defer f.mutex.Unlock()
	if f.manSig == nil {
		f.manSig = make(chan interface{}, 1)
	}
	return f.manSig
}
func (f *Finisher) Add(srv Server, opts ...Option) {
	keeper := &serverKeeper{
		srv:     srv,
		timeout: f.timeout(),
	}
	for _, opt := range opts {
		if err := opt(keeper); err != nil {
			panic(err)
		}
	}
	f.keepers = append(f.keepers, keeper)
}
func (f *Finisher) Wait() {
	f.updateNames()
	signals := f.signals()
	stop := make(chan os.Signal, len(signals))
	signal.Notify(stop, signals...)
	select {
	case sig := <-stop:
		if sig == syscall.SIGINT {
			fmt.Println("")
		}
	case <-f.getManSig():
	}
	f.log().Infof("finish: shutdown signal received")
	for _, keeper := range f.keepers {
		ctx, cancel := context.WithTimeout(context.Background(), keeper.timeout)
		defer cancel()
		f.log().Infof("finish: shutting down %s ...", keeper.name)
		err := keeper.srv.Shutdown(ctx)
		if err != nil {
			if err == context.DeadlineExceeded {
				f.log().Errorf("finish: shutdown timeout for %s", keeper.name)
			} else {
				f.log().Errorf("finish: error while shutting down %s: %s", keeper.name, err)
			}
		} else {
			f.log().Infof("finish: %s closed", keeper.name)
		}
	}
}