diff --git a/examples/routines/main.go b/examples/routines/main.go new file mode 100644 index 0000000..cb0b493 --- /dev/null +++ b/examples/routines/main.go @@ -0,0 +1,114 @@ +// 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 { } { } + } + } + } +}