backoff/cli/main.go

92 lines
2.5 KiB
Go
Raw Permalink Normal View History

2026-02-08 15:20:10 -05:00
package main
import (
"backoff/fibonacci"
"context"
"flag"
"fmt"
"math"
"os"
"strconv"
2026-02-09 19:36:33 -05:00
"strings"
2026-02-08 15:20:10 -05:00
"time"
)
2026-02-09 19:36:33 -05:00
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)
2026-02-08 15:20:10 -05:00
default:
2026-02-09 19:36:33 -05:00
fmt.Fprintf(os.Stderr, "warning: unknown format %q - using 'string'\n", format)
results = pause.String()
2026-02-08 15:20:10 -05:00
}
2026-02-09 19:36:33 -05:00
return results
2026-02-08 15:20:10 -05:00
}
2026-02-09 19:36:33 -05:00
type OutputFormat string
const (
SECONDS OutputFormat = "s"
MILLISECONDS OutputFormat = "ms"
MICROSECONDS OutputFormat = "us"
)
2026-02-08 15:20:10 -05:00
func main() {
start := time.Now()
var (
2026-02-09 19:36:33 -05:00
doPanic bool
doSleep bool
multiplier time.Duration
jitter time.Duration
iteration int64
outputformat string
2026-02-08 15:20:10 -05:00
)
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.")
2026-02-09 19:36:33 -05:00
flag.StringVar(&outputformat, "format", "string", "output format - s, ms, us, µs, ns, string")
2026-02-08 15:20:10 -05:00
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())
2026-02-09 19:36:33 -05:00
response = FormatOutput(time.Since(start), outputformat)
2026-02-08 15:20:10 -05:00
default:
2026-02-09 19:36:33 -05:00
response = FormatOutput(backoff.Next(), outputformat)
2026-02-08 15:20:10 -05:00
}
fmt.Println(response)
}