package main import ( "backoff/fibonacci" "context" "flag" "fmt" "math" "os" "strconv" "strings" "time" ) func FormatOutput(pause time.Duration, format string) string { var results string switch strings.ToLower(format) { case "string": results = pause.String() case "s": results = fmt.Sprintf("%f", pause.Seconds()) case "ms": results = strconv.FormatInt(pause.Milliseconds(), 10) case "us", "µs": results = strconv.FormatInt(pause.Microseconds(), 10) case "ns": results = strconv.FormatInt(pause.Nanoseconds(), 10) default: fmt.Fprintf(os.Stderr, "warning: unknown format %q - using 'string'\n", format) results = pause.String() } return results } type OutputFormat string const ( SECONDS OutputFormat = "s" MILLISECONDS OutputFormat = "ms" MICROSECONDS OutputFormat = "us" ) func main() { start := time.Now() var ( doPanic bool doSleep bool multiplier time.Duration jitter time.Duration iteration int64 outputformat string ) flag.BoolVar(&doPanic, "panic", false, "panic instead of overflowing values (default returns the max value instead of overflowing).") flag.BoolVar(&doSleep, "sleep", false, "sleep for the resulting duration after calculating it. prints the run duration of the program instead of the calculated pause duration.") flag.DurationVar(&multiplier, "multiplier", time.Millisecond, "pause multiplier.") flag.DurationVar(&jitter, "jitter", 0, "jitter boundary. pause duration is randomly selected in the range of resultDuration+-jitter.") flag.Int64Var(&iteration, "iteration", 1, "iteration to use for calculating pause time.") flag.StringVar(&outputformat, "format", "string", "output format - s, ms, us, µs, ns, string") flag.Parse() if jitter < 0 { jitter = time.Duration(int(math.Abs(float64(jitter.Nanoseconds())))) } if iteration >= int64(len(fibonacci.TheFibonacciSequence)) { switch doPanic { case true: panic(fmt.Sprintf("error: input %d would overflow int64\n", iteration)) default: maxIteration := int64(len(fibonacci.TheFibonacciSequence) - 1) fmt.Fprintf(os.Stderr, "iteration %d would overflow int64 - using %d\n", iteration, maxIteration) iteration = maxIteration } } backoff := &fibonacci.FibonacciBackoff{ Iteration: iteration, PauseMultiplier: multiplier, Jitter: jitter, } var response string switch doSleep { case true: <-backoff.After(context.Background()) response = FormatOutput(time.Since(start), outputformat) default: response = FormatOutput(backoff.Next(), outputformat) } fmt.Println(response) }