Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
package main
import (
"errors"
"fmt"
"os"
"time"
pipe "gopkg.in/pipe.v2"
)
const timespecSep = ':'
const usage = `
restart runs a process and restart it when it ends or after a specified interval.
Call as
restart TIMESPEC COMMAND ARGUMENTS...
with TIMESPEC <start>:<each>, e.g. 4h:24h for a forced restart each 24 hours, starting in 4 hours.
TIMESPEC may only contain one value when <start> and <each> are the same.
Valid units: "ns", "us", "ms", "s", "m", "h" (nano, micro, milli, ...)
`
func main() {
var (
err error
timespec string
cmd string
args []string
startingTxt string
intervalTxt string
start time.Duration
interval time.Duration
)
if len(os.Args) >= 3 {
timespec, cmd, args = os.Args[1], os.Args[2], os.Args[3:]
intervalTxt = timespec
for i := range timespec {
if timespec[i] == timespecSep {
startingTxt, intervalTxt = timespec[:i], timespec[i+1:]
}
}
if len(startingTxt) > 0 {
start, err = time.ParseDuration(startingTxt)
if err != nil {
err = errors.New("start time format: " + err.Error())
}
}
interval, err = time.ParseDuration(intervalTxt)
if err != nil {
err = errors.New("interval time format: " + err.Error())
}
} else {
err = errors.New("too few arguments")
}
if err != nil {
fmt.Fprintln(os.Stderr, err, usage)
os.Exit(-1)
}
fmt.Printf("[[STARTING]] %s\n", time.Now().Format(time.RFC3339))
for {
state := pipe.NewState(os.Stdout, os.Stderr)
state.Timeout = start
start = interval
p := pipe.Exec(cmd, args...)
err := p(state)
if err == nil {
err = state.RunTasks()
}
if err == nil {
fmt.Printf("[[RESTARTING - process ended]] %s\n", time.Now().Format(time.RFC3339))
continue
}
if err.Error() == pipe.ErrTimeout.Error() {
fmt.Printf("[[RESTARTING - after %s]] %s\n",
state.Timeout,
time.Now().Format(time.RFC3339),
)
continue
}
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment