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 )
}