v/cmd/tools/vretry.v

58 lines
1.5 KiB
V

import os
import time
import flag
struct Context {
mut:
show_help bool
timeout time.Duration
delay time.Duration
retries int
}
fn main() {
mut context := Context{}
args := os.args#[1..]
// dump(args)
mut fp := flag.new_flag_parser(args)
fp.application('v retry')
fp.version('0.0.1')
fp.description('Run the command CMD in a loop, until it succeeds, or until a predetermined amount of seconds pass.')
fp.arguments_description('CMD')
fp.skip_executable()
fp.limit_free_args_to_at_least(1)!
context.show_help = fp.bool('help', `h`, false, 'Show this help screen.')
context.timeout = fp.float('timeout', `t`, 900.0, 'Timeout in seconds (for all retries). Default: 900.0 seconds (15 minutes).') * time.second
context.delay = fp.float('delay', `d`, 1.0, 'Delay between each retry in seconds. Default: 1.0 second.') * time.second
context.retries = fp.int('retries', `r`, 10, 'Maximum number of retries. Default: 10.')
if context.show_help {
println(fp.usage())
exit(0)
}
command_args := fp.finalize() or {
eprintln('error: ${err}')
exit(1)
}
cmd := command_args.join(' ')
// dump(cmd)
spawn fn (context Context) {
time.sleep(context.timeout)
eprintln('error: exceeded maximum timeout (${context.timeout.seconds()}s)!')
exit(1)
}(context)
mut res := 0
for i in 0 .. context.retries {
res = os.system(cmd)
if res == 0 {
break
}
if i == context.retries - 1 {
eprintln('error: exceeded maximum number of retries (${context.retries})!')
exit(res)
}
time.sleep(context.delay)
}
exit(res)
}