Skip to content

Instantly share code, notes, and snippets.

@calvernaz
Created December 29, 2018 22:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save calvernaz/aae613c425c0fc05bab7b8e1b992d6e1 to your computer and use it in GitHub Desktop.
Save calvernaz/aae613c425c0fc05bab7b8e1b992d6e1 to your computer and use it in GitHub Desktop.
ticker set
package main
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
"math/rand"
)
type tickResult struct {
tick time.Time
result interface{}
}
type TickerSet struct {
tc []*T
ch chan *tickResult
}
func NewTickerSet(ch chan *tickResult) *TickerSet {
return &TickerSet{
tc: make([]*T, 0),
ch: ch,
}
}
func (s *TickerSet) Add(tck ...*T) {
s.tc = append(s.tc, tck...)
}
func (s *TickerSet) Stop(tck ...*T) {
for _, ol := range tck {
for i, il := range s.tc {
if ol == il {
il.Timer.Stop()
s.delete(i)
break
}
}
}
}
// TODO: should be hidden ?!
func (s *TickerSet) Tickers() []*T {
return s.tc
}
func (s *TickerSet) Run() {
for _, t := range s.tc {
go func(t *T) {
for tick := range t.Timer.C {
s.ch <- &tickResult {
tick: tick,
result: t.Fn(),
}
}
}(t)
}
}
func (s *TickerSet) delete(i int) {
s.tc[i] = s.tc[len(s.tc)-1]
s.tc[len(s.tc)-1] = nil // or the zero value of T
s.tc = s.tc[:len(s.tc)-1]
}
type T struct {
Timer *time.Ticker
Description string
Fn func() interface{}
}
func main() {
ch := make(chan *tickResult)
ts := NewTickerSet(ch)
fn := func() interface{} {
return "fn"
}
t1 := &T{
time.NewTicker(1 * time.Second),
"One second tick",
fn,
} // 1 second Tick
fn2 := func() interface {} {
x := 0
for i := 0; i < 1000000; i++ {
x = x + rand.Int() * i
}
return x
}
t2 := &T{
time.NewTicker(5 * time.Second),
"Five second tick",
fn2,
} // 5 second Tick
// Add tickers to set
ts.Add(t1, t2)
// Wait for results from the tickers
go func() {
for {
select {
case result := <-ch:
fmt.Printf("tick: %v, result: %v\n", result.tick, result.result)
}
}
}()
ts.Run()
// stop the tickers after 20 seconds
time.AfterFunc(20*time.Second, func() {
ts.Stop(t1, t2)
fmt.Printf("TicketSet size: %d\n", len(ts.Tickers()))
})
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
select {
case sig := <-sig:
log.Printf("Signal %s received, shutting down.", sig)
close(ch)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment