func (tm *Timer) Stop() {
	tm.mu.Lock()
	defer tm.mu.Unlock()
	if tm.running {
		tm.msg <- timerStop
		tm.running = false
	}
}
Stop will stop the timer. It guarantees that the timer will not execute
any more calls to keephouse once it has returned.
package timer
import (
	"sync"
	"time"
	"github.com/nooncall/shazam/util/sync2"
)
type typeAction int
const (
	timerStop typeAction = iota
	timerReset
	timerTrigger
)
type Timer struct {
	interval sync2.AtomicDuration
	mu      sync.Mutex
	running bool
	msg chan typeAction
}
func NewTimer(interval time.Duration) *Timer {
	tm := &Timer{
		msg: make(chan typeAction),
	}
	tm.interval.Set(interval)
	return tm
}
func (tm *Timer) Start(keephouse func()) {
	tm.mu.Lock()
	defer tm.mu.Unlock()
	if tm.running {
		return
	}
	tm.running = true
	go tm.run(keephouse)
}
func (tm *Timer) run(keephouse func()) {
	for {
		var ch <-chan time.Time
		interval := tm.interval.Get()
		if interval <= 0 {
			ch = nil
		} else {
			ch = time.After(interval)
		}
		select {
		case action := <-tm.msg:
			switch action {
			case timerStop:
				return
			case timerReset:
				continue
			}
		case <-ch:
		}
		keephouse()
	}
}
func (tm *Timer) SetInterval(ns time.Duration) {
	tm.interval.Set(ns)
	tm.mu.Lock()
	defer tm.mu.Unlock()
	if tm.running {
		tm.msg <- timerReset
	}
}
func (tm *Timer) Trigger() {
	tm.mu.Lock()
	defer tm.mu.Unlock()
	if tm.running {
		tm.msg <- timerTrigger
	}
}
func (tm *Timer) TriggerAfter(duration time.Duration) {
	go func() {
		time.Sleep(duration)
		tm.Trigger()
	}()
}