func (t *logicalTicker) fireRoutine(interval time.Duration) {
	source := t.source
	lasttime := time.Time{}
	select {
	case lasttime = <-source:
	case <-t.quit:
		return
	}
	for {
		select {
		case newtime := <-source:
			elapsed := newtime.Sub(lasttime)
			if interval <= elapsed {
				select {
				case t.ch <- newtime:
				case <-t.quit:
					return
				}
				lasttime = newtime
			}
		case <-t.quit:
			return  
		}
	}
}
We need a goroutine to read times from t.source
and fire on t.Chan() when `interval` has passed.
package common
import (
	"sync"
	"time"
)
type TickerMaker func(dur time.Duration) Ticker
type Ticker interface {
	Chan() <-chan time.Time
	Stop()
}
var _ Ticker = (*defaultTicker)(nil)
type defaultTicker time.Ticker
func defaultTickerMaker(dur time.Duration) Ticker {
	ticker := time.NewTicker(dur)
	return (*defaultTicker)(ticker)
}
func (t *defaultTicker) Chan() <-chan time.Time {
	return t.C
}
func (t *defaultTicker) Stop() {
	((*time.Ticker)(t)).Stop()
}
func NewLogicalTickerMaker(source chan time.Time) TickerMaker {
	return func(dur time.Duration) Ticker {
		return newLogicalTicker(source, dur)
	}
}
type logicalTicker struct {
	source <-chan time.Time
	ch     chan time.Time
	quit   chan struct{}
}
func newLogicalTicker(source <-chan time.Time, interval time.Duration) Ticker {
	lt := &logicalTicker{
		source: source,
		ch:     make(chan time.Time),
		quit:   make(chan struct{}),
	}
	go lt.fireRoutine(interval)
	return lt
}