sysvinit like task runner in go
must := func(err error) {
if err != nil {
log.Fatal(err)
}
}
r := gotask.NewRunner()
must(r.QuickAdd("a", initAFunc))
must(r.Add(gotask.New("b", initBFunc, []string{"a"}))
if err := r.RunSync(); err != nil {
log.Fatal(err)
}
In this example, it starts pgsql and redis via systemd, warm-up the cache before start the service.
It uses routines package
var runner = gotask.NewRunner()
func must(e error) {
if e != nil {
log.Fatal(e)
}
}
func systemdStart(srv string) (err error) {
if err := exec.Command("systemctl", "start", srv).Run(); err != nil {
return
}
// check 3 times every 10 sec
err = routines.TryAtMost(3, routines.RunAtLeast(
10 * time.Second,
func() error { return exec.Command("systemctl", "status", srv).Run() },
))
return
}
func init() {
must(runner.QuickAdd("pgsql", func() error { return systemdStart("postgresql") }))
must(runner.QuickAdd("redis", func() error { return systemdStart("redis") }))
}
func fillCache() error {
// TBD
return nil
}
func init() {
must(runner.Add("warm-up", fillCache, []string{
"prepareConn",
}))
}
var dbConn *sql.DB
var cacheConn *redis.Client
func prepareConn() error {
// TBD: setup dbConn and cacheConn
return nil
}
func init() {
must(runner.Add("prepareConn", prepareConn, []string{
"pgsql", "redis",
}))
}
func main() {
if err := runner.Run(2); err != nil {
log.Fatal(runner.Errors())
}
log.Print(myservicepkg.Start())
}
By using Only()
, Without()
, With()
and Skip()
, it is possible to split tasks in to several groups.
r := NewRunner()
r.QuickAdd("a", funcA)
r.Add(New("b", funcB, "a")
r.QuickAdd("c", funcC)
r.Add(New("d", funcD, "c", "a")
groupB := r.With("b")
groupB.Run() // runs task a and b
// skip tasks ran in groupB to prevent running same task twice
r.Skip(groupb.Tasks()...)
r.Run() // runs task c and d
Copyright Chung-Ping Jen [email protected] 2021-
MPL v2.0