| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 | 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()	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.mu.Unlock()}func (t *Timer) StopAll() {	t.log.Println("[TIMER] StopAll")	t.mu.Lock()	for _, cancel := range t.idx {		cancel()	}	t.idx = make(map[string]context.CancelFunc)	t.mu.Unlock()}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}
 |