package go_lazy_quiter import ( "context" "os" "os/signal" ) type RunGroupQuiter struct { qchan chan os.Signal ctx context.Context cncl context.CancelFunc SignalNotifyFunc func(sig os.Signal) } func NewRunGroupQuiter(sig ...os.Signal) *RunGroupQuiter { r := &RunGroupQuiter{qchan: make(chan os.Signal, 0)} if sig == nil { sig = []os.Signal{ os.Interrupt, os.Kill, } } signal.Notify(r.qchan, sig...) return r } func (q *RunGroupQuiter) Run() error { q.ctx, q.cncl = context.WithCancel(context.Background()) select { case <-q.ctx.Done(): { close(q.qchan) return nil } case sig := <-q.qchan: { if q.cncl != nil { q.cncl() } if q.SignalNotifyFunc != nil { q.SignalNotifyFunc(sig) } return nil } } } func (q *RunGroupQuiter) Stop(err error) { if q.cncl != nil { q.cncl() } }