package main

import "time"

type Worker struct {
	Act      func()
	Finalize func()
	Interval time.Duration
	done     chan bool
	ticker   *time.Ticker
}

func (w *Worker) Start() {
	w.ticker = time.NewTicker(w.Interval)
	w.done = make(chan bool, 1)
	go w.run()
}

func (w *Worker) run() {
	for {
		select {
		case <-w.ticker.C:
			w.Act()
		case <-w.done:
			return
		}
	}
}

func (w *Worker) Stop() {
	w.ticker.Stop()
	w.done <- true
	if w.Finalize != nil {
		w.Finalize()
	}
}

func main() {
	c := 0
	w := &Worker{
		Act:      func() { c++ },
		Finalize: func() { c = 0 },
		Interval: 99 * time.Millisecond,
	}
	w.Start()
	println(c)
	time.Sleep(1 * time.Second)
	println(c)
	time.Sleep(1 * time.Second)
	println(c)
	w.Stop()
	println(c)
}
