package foo import ( "time" "github.com/dimonomid/clock" ) type Foo struct { nextNum int out chan<- int clock clock.Clock } type FooParams struct { Clock clock.Clock // Out is the channel to deliver numbers to Out chan<- int // Interval is how often to deliver numbers to Out Interval time.Duration } // NewFoo creates and returns an instance of Foo, and also starts an internal // goroutine which will send numbers to the provided channel params.Out. func NewFoo(params *FooParams) *Foo { if params.Clock == nil { panic("Clock is required") } foo := &Foo{ clock: params.Clock, out: params.Out, } go foo.run(params.Interval) return foo } func (foo *Foo) run(interval time.Duration) { // NOTE: there is an issue with creating ticker right in this goroutine, // explained below. ticker := foo.clock.Ticker(interval) for { <-ticker.C foo.out <- foo.nextNum foo.nextNum += 1 } }