// Example routines demonstrates the use of routines and a routine manager. package main import "log" import "time" import "context" import "math/rand" import "git.tebibyte.media/sashakoshka/go-service/daemon" import "git.tebibyte.media/sashakoshka/go-service/routines" func main () { cow := cow { name: "cow" } sheep := sheep { name: "sheep" } horse := horse { name: "horse", sheep: &sheep, } manager := routines.Manager { Routines: []routines.Routine { &cow, &sheep, &horse, }, } ctx, cancel := context.WithTimeout(context.Background(), time.Second * 12) daemon.OnSigint(cancel) err := manager.Run(ctx) if err != nil { log.Fatalln(err) } } type cow struct { name string } func (this *cow) Init (ctx context.Context) error { log.Printf("%s: waking up\n", this.name) defer log.Printf("%s: woke up\n", this.name) time.Sleep(time.Duration(float64(time.Second) * 4 * rand.Float64())) return nil } func (this *cow) Run (ctx context.Context) error { log.Printf("%s: running\n", this.name) defer log.Printf("%s: going to sleep\n", this.name) ticker := time.NewTicker(time.Duration(float64(time.Second) * 4 * rand.Float64())) defer ticker.Stop() for { select { case <- ctx.Done(): return ctx.Err() case <- ticker.C: log.Printf("%s: moo\n", this.name) } } } type sheep struct { name string poke chan struct { } } func (this *sheep) Init (ctx context.Context) error { log.Printf("%s: waking up\n", this.name) defer log.Printf("%s: woke up\n", this.name) this.poke = make(chan struct { }) time.Sleep(time.Duration(float64(time.Second) * 4 * rand.Float64())) return nil } func (this *sheep) Run (ctx context.Context) error { log.Printf("%s: running\n", this.name) defer log.Printf("%s: going to sleep\n", this.name) for { select { case <- ctx.Done(): return ctx.Err() case <- this.poke: log.Printf("%s: baa\n", this.name) } } } type horse struct { name string sheep *sheep } func (this *horse) Init (ctx context.Context) error { log.Printf("%s: waking up\n", this.name) defer log.Printf("%s: woke up\n", this.name) time.Sleep(time.Duration(float64(time.Second) * 4 * rand.Float64())) return nil } func (this *horse) Run (ctx context.Context) error { log.Printf("%s: running\n", this.name) defer log.Printf("%s: going to sleep\n", this.name) ticker := time.NewTicker(time.Duration(float64(time.Second) * 4 * rand.Float64())) defer ticker.Stop() for { select { case <- ctx.Done(): return ctx.Err() case <- ticker.C: if this.sheep != nil { log.Printf("%s: poking %s\n", this.name, this.sheep.name) this.sheep.poke <- struct { } { } } } } }