commit 4a9fc3008524cf23e1a3ff372325f93b299e7cc5 Author: Neville Kadwa Date: Thu Mar 26 14:50:34 2015 -0400 initial commit diff --git a/bin/retry b/bin/retry new file mode 100755 index 0000000..b121c89 --- /dev/null +++ b/bin/retry @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby + +require 'rubygems' + +require File.expand_path("../../lib/retryit.rb", __FILE__) + +RetryIt.new.run(ARGV) diff --git a/lib/retryit.rb b/lib/retryit.rb new file mode 100644 index 0000000..fce2ead --- /dev/null +++ b/lib/retryit.rb @@ -0,0 +1,80 @@ +require 'optparse' + + +class RetryIt + + attr_accessor :max_retries, :min_sleep, :max_sleep, :constant_sleep + + def initialize() + @max_tries = 10 + @min_sleep = 0.3 + @max_sleep = 60.0 + @constant_sleep = nil + end + + def load_options(args) + return if args.size < 1 + + optparser = OptionParser.new do |opts| + opts.banner = "Usage: retry [options] -e execute command" + + opts.on("-t#", "--tries=#", Integer, "Set max retries: Default 10") do |v| + @max_tries = v + end + + opts.on("-s#", "--sleep=secs", Float, "Constant sleep amount (seconds)") do |v| + @constant_sleep = v + end + + opts.on("--min=secs", Float, "Exponenetial Backoff: minimum sleep amount (seconds): Default 0.3") do |v| + @min_sleep = v + end + + opts.on("--max=secs", Float, "Exponenetial Backoff: maximum sleep amount (seconds): Default 60") do |v| + @max_sleep = v + end + + end + + optparser.parse(*args) + end + + def sleep_amount(attempts) + @constant_sleep || [@min_sleep * (2 ** (attempts - 1)), @max_sleep].min + end + + def log_out(message) + STDERR.puts(message) + end + + def run(args) + + idx = args.find_index("-e") + if !idx.nil? + load_options(args[0...idx]) + args = args[(idx+1)..-1] + end + + raise "max_tries must be greater than 0" unless @max_tries > 0 + raise "minimum sleep cannot be greater than maximum sleep" unless @max_sleep >= @min_sleep + raise "unknown execute command" unless args.size > 0 + + process = nil + attempts = 0 + success = false + while (success == false && attempts <= @max_tries) + if (attempts > 0) + sleep_time = sleep_amount(attempts) + log_out("Before retry ##{attempts}: sleeping #{sleep_time} seconds") + sleep sleep_time + end + success = system(args[0], *args[1..-1]) + process = $? + attempts += 1 + end + + log_out("Command Failed: #{args[0]}") if success.nil? + exit process.exitstatus + end + +end diff --git a/retryit.gemspec b/retryit.gemspec new file mode 100644 index 0000000..1e1a742 --- /dev/null +++ b/retryit.gemspec @@ -0,0 +1,15 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = 'retryit' + s.version = '0.1.0' + s.summary = "retry any command line" + s.description = "General purpose retry cli program for anything" + s.authors = ["Neville Kadwa"] + s.email = ["neville@kadwa.com"] + s.files = Dir['lib/**/*.rb'] + Dir['bin/*'] + Dir['[A-Z]*'] + s.test_files = Dir['test/**/*'] + s.executables = Dir['bin/**/*'].map{|f| File.basename(f)} + s.homepage = 'http://github.com/kadwanev/retry' + s.licenses = ['Apache-2.0'] +end