Created
December 29, 2018 22:30
-
-
Save calvernaz/aae613c425c0fc05bab7b8e1b992d6e1 to your computer and use it in GitHub Desktop.
ticker set
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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