| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 | package signalimport (	"sync"	"time")// PeriodicTask is a task that runs periodically.type PeriodicTask struct {	// Interval of the task being run	Interval time.Duration	// Execute is the task function	Execute func() error	access sync.Mutex	timer  *time.Timer	closed bool}func (t *PeriodicTask) checkedExecute() error {	t.access.Lock()	defer t.access.Unlock()	if t.closed {		return nil	}	if err := t.Execute(); err != nil {		return err	}	t.timer = time.AfterFunc(t.Interval, func() {		t.checkedExecute()	})	return nil}// Start implements common.Runnable. Start must not be called multiple times without Close being called.func (t *PeriodicTask) Start() error {	t.access.Lock()	t.closed = false	t.access.Unlock()	if err := t.checkedExecute(); err != nil {		t.closed = true		return err	}	return nil}// Close implements common.Closable.func (t *PeriodicTask) Close() error {	t.access.Lock()	defer t.access.Unlock()	t.closed = true	if t.timer != nil {		t.timer.Stop()		t.timer = nil	}	return nil}
 |