| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 | package timerimport (	"context"	"sync"	"time")type Logger interface {	Println(f string, v ...any)}type Handler func() errortype Timer struct {	idx map[string]context.CancelFunc	log Logger	mu  sync.Mutex}func (t *Timer) Register(name string, handler Handler, d time.Duration) {	t.mu.Lock()	if _, ok := t.idx[name]; ok {		panic("duplicate name:" + name)	}	ctx, cancel := context.WithCancel(context.Background())	go t.handleRegister(ctx, name, handler, d)	t.idx[name] = cancel	t.mu.Unlock()}func (t *Timer) Stop(name string) {	t.mu.Lock()	cancel, ok := t.idx[name]	if ok {		cancel()		delete(t.idx, name)		t.log.Println("[Timer] Stop: stopped %s", name)	}	t.mu.Unlock()}func (t *Timer) StopAll() {	t.log.Println("[Timer] StopAll: starting")	t.mu.Lock()	for name, cancel := range t.idx {		cancel()		t.log.Println("[Timer] StopAll: stopped %s", name)	}	t.idx = make(map[string]context.CancelFunc)	t.mu.Unlock()	t.log.Println("[Timer] StopAll: done")}func (t *Timer) handleRegister(ctx context.Context, name string, handler Handler, d time.Duration) {	t.log.Println("[Timer] %s: cycle time: %s with started", name, d)	tim := time.NewTimer(d)	for {		select {		case <-ctx.Done():			t.log.Println("[Timer] %s: stopped", name)			return		case <-tim.C:			t.log.Println("[Timer] %s: executing", name)			if err := handler(); err != nil {				t.log.Println("[Timer] %s: exec failed: %s", name, err)			} else {				t.log.Println("[Timer] %s: exec succeeded", name)			}			tim.Reset(d)		}	}}func New(logger Logger) *Timer {	t := new(Timer)	t.idx = make(map[string]context.CancelFunc)	t.log = logger	return t}
 |