go-service/examples/routines/main.go

115 lines
2.6 KiB
Go

// 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 { } { }
}
}
}
}