mycommon/graceful/graeceful.go

80 lines
1.0 KiB
Go

package graceful
import (
"context"
"golang.org/x/sync/errgroup"
"log"
"os"
"os/signal"
"syscall"
)
func init() {
log.SetOutput(os.Stdout)
}
type IRunner interface {
Run(ctx context.Context) error
Stop()
}
type Graceful struct{}
type Opt func(*Graceful)
func New() *Graceful {
return &Graceful{}
}
func (g *Graceful) Run(r ...IRunner) {
eg := &errgroup.Group{}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
for _, v := range r {
goRun(ctx, eg, v)
}
eg.Go(func() error {
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
select {
case v := <-ch:
log.Printf("catch notfiy stop: %v", v)
}
cancel()
for _, v := range r {
v.Stop()
}
return nil
})
defer func() {
log.Printf("server stop")
}()
err := eg.Wait()
if err != nil {
log.Println(err)
return
}
}
func goRun(ctx context.Context, eg *errgroup.Group, r IRunner) {
eg.Go(func() error {
err := r.Run(ctx)
if err != nil {
log.Printf("run err: %s", err)
return err
}
return nil
})
}