greenjaguar 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3ea25f0dabc607887639c7464307e62e12b80e3f
4
+ data.tar.gz: cb247a82fc96793de4c6bbb8da97a59b3c7da30e
5
+ SHA512:
6
+ metadata.gz: d2bd34a55d564d49e9c5fa82674a3c5b4a950d9313575230ff5f417ddd9f25ebc96e75075013908b0acde767e6e3748840911e4f317664e68ec4de816eca0efe
7
+ data.tar.gz: ddb3c0705c9ec28d82bdaeeb2e5278a958ec96f2453d55de2215d8d58745cc5cab184788371072f81bb7803d9f6095368a38bb0f0f646222964c79165565421c
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .idea
16
+ .DS_Store
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.6
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm: 2.2.3
3
+ notifications:
4
+ email:
5
+ recipients:
6
+ - anides84@hotmail.com
7
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in greenjaguar.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,11 @@
1
+ guard 'rspec', cmd: "bundle exec rspec" do
2
+ # watch /lib/ files
3
+ watch(%r{^lib/(.+).rb$}) do |m|
4
+ "spec/#{m[1]}_spec.rb"
5
+ end
6
+
7
+ # watch /spec/ files
8
+ watch(%r{^spec/(.+).rb$}) do |m|
9
+ "spec/#{m[1]}.rb"
10
+ end
11
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Aniruddha Deshpande
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ Note: **Not Production ready yet**
2
+
3
+ # Greenjaguar [![Build Status](https://travis-ci.org/aniruddha84/greenjaguar.svg?branch=master)](https://travis-ci.org/aniruddha84/greenjaguar)
4
+
5
+ Applies retry behavior to arbitrary code blocks with different policies like fibonacci,
6
+ exponential backoff, FixedInterval, etc. This basically is the 'retry' construct on steroids.
7
+
8
+ Potential uses are for accessing cloud-based services that experience transient faults. We should encapsulate our calls
9
+ with appropriate retry policies to make our applications more robust.
10
+
11
+ Features:
12
+ * It currently supports following retry policies:
13
+ * Default (no wait)
14
+ * Fibonacci (wait times between retries increase in fibonacci sequence)
15
+ * ExponentialBackOff (wait times increase using exponential backoff)
16
+ * Random (wait times between retries vary between 0 - 5 sec/ms)
17
+ * FixedInterval (wait every 'n' sec/ms)
18
+ * You can specify the time unit for retry (:sec or :ms). Default is seconds.
19
+ * You can specify the Exception Types for which Retrier should execute. Default is all.
20
+ * You can specify that Retrier should fail silently (i.e. it wont raise any error if all retries fail)
21
+
22
+ If all retries fail, the last exception will be raised.
23
+
24
+ ## Installation
25
+
26
+ Add this line to your application's Gemfile:
27
+
28
+ ```ruby
29
+ gem 'greenjaguar'
30
+ ```
31
+
32
+ And then execute:
33
+
34
+ $ bundle
35
+
36
+ Or install it yourself as:
37
+
38
+ $ gem install greenjaguar
39
+
40
+ ## Usage
41
+ ```ruby
42
+ class YourClass
43
+ include Greenjaguar
44
+
45
+ def your_method
46
+ # Build retry policy
47
+ @policy = build_policy do
48
+ retry_times 10
49
+ with_strategy :exponential_backoff
50
+ measure_time_in :ms
51
+ only_on_exceptions [Net::HTTPError]
52
+ end
53
+
54
+ # Executes your code using the policy
55
+ robust_retry(@policy) do
56
+ # Your code goes here
57
+ end
58
+ end
59
+ end
60
+ ```
61
+ In the above example your code block is passed to Greenjaguar which executes it 11 times
62
+ (first call + 10 retry attempts, in case of failures).
63
+ If all calls fail, the last exception is raised. Retry happens only if the error raised is of the
64
+ specified type.
65
+
66
+ ## Issues
67
+
68
+ 1. Need more tests.
69
+ 2. Need logo.
70
+
71
+ ## Contributing
72
+
73
+ 1. Fork it ( https://github.com/[my-github-username]/greenjaguar/fork )
74
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
76
+ 4. Push to the branch (`git push origin my-new-feature`)
77
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'bundler/gem_tasks'
3
+
4
+ # Default directory to look in is `/specs`
5
+ # Run with `rake spec`
6
+ RSpec::Core::RakeTask.new(:spec) do |task|
7
+ task.rspec_opts = ['--color', '--format', 'documentation']
8
+ end
9
+
10
+ task :default => :spec
11
+
12
+
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'greenjaguar/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "greenjaguar"
8
+ spec.version = Greenjaguar::VERSION
9
+ spec.authors = ["Aniruddha Deshpande"]
10
+ spec.email = ["anides84 AT hotmail DOT com"]
11
+ spec.summary = %q{Applies retry behavior to arbitrary code blocks with different policies like fibonacci,
12
+ exponential backoff, FixedInterval, etc. This basically is the 'retry' construct on steroids.}
13
+ spec.description = ""
14
+ spec.homepage = "https://github.com/aniruddha84/greenjaguar"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.2"
25
+ spec.add_development_dependency "guard", "~> 2.12"
26
+ spec.add_development_dependency "guard-rspec", "~> 4.6"
27
+ spec.add_development_dependency "byebug", "~> 6.0"
28
+ spec.add_development_dependency "webmock", "~> 1.21"
29
+ end
@@ -0,0 +1,91 @@
1
+ module Greenjaguar
2
+ class PolicyBuilder
3
+ attr_accessor :count, :wait_strategy, :timeout, :logger, :strategy, :exceptions
4
+
5
+ def initialize(&block)
6
+ @count = 1
7
+ @timeout = 300
8
+ @exceptions = []
9
+ instance_eval(&block)
10
+ end
11
+
12
+ def retry_times(retry_count)
13
+ @count = retry_count
14
+ self
15
+ end
16
+
17
+ def should_timeout_after(retry_timeout)
18
+ @timeout = retry_timeout
19
+ self
20
+ end
21
+
22
+ def use_logger(logger)
23
+ @logger = logger
24
+ self
25
+ end
26
+
27
+ def fail_silently
28
+ @fail_silently = true
29
+ end
30
+
31
+ def fail_silently?
32
+ @fail_silently
33
+ end
34
+
35
+ def never_give_up
36
+ @count = -1
37
+ end
38
+
39
+ def never_give_up?
40
+ @count == -1
41
+ end
42
+
43
+ def measure_time_in(time_unit)
44
+ @strategy.time_unit = time_unit
45
+ self
46
+ end
47
+
48
+ def with_strategy(wait_strategy, *args)
49
+ @strategy = init_wait_strategy(wait_strategy, *args)
50
+ self
51
+ end
52
+
53
+ def only_on_exceptions(exception_array)
54
+ @exceptions.concat exception_array
55
+ end
56
+
57
+ def valid_exception?(exception)
58
+ if @exceptions.empty?
59
+ return true
60
+ else
61
+ @exceptions.each {|ex| return true if exception.class <= ex}
62
+ end
63
+ false
64
+ end
65
+
66
+ def wait
67
+ strategy.wait
68
+ end
69
+
70
+ private
71
+
72
+ def strategy
73
+ @strategy ||= init_wait_strategy(:default)
74
+ end
75
+
76
+ def init_wait_strategy(wait_strategy, *args)
77
+ case wait_strategy
78
+ when :fibonacci
79
+ return Greenjaguar::Strategies::FibonacciStrategy.new
80
+ when :exponential_backoff
81
+ return Greenjaguar::Strategies::ExponentialBackoffStrategy.new
82
+ when :random
83
+ return Greenjaguar::Strategies::RandomStrategy.new
84
+ when :fixed_interval
85
+ return Greenjaguar::Strategies::FixedIntervalStrategy.new(*args)
86
+ else
87
+ return Greenjaguar::Strategies::DefaultWaitStrategy.new
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,44 @@
1
+ module Greenjaguar
2
+ class Retrier
3
+
4
+ def initialize(policy, &block)
5
+ @policy = policy
6
+ @retry_block = block
7
+ exec
8
+ end
9
+
10
+ private
11
+ def exec
12
+ @start_time = Time.new
13
+ begin
14
+ @retry_block.call
15
+ rescue => e
16
+ raise unless @policy.valid_exception? e
17
+ if @policy.never_give_up?
18
+ @policy.wait
19
+ retry
20
+ else
21
+ if time_out? || retry_count_reached?
22
+ raise unless @policy.fail_silently?
23
+ else
24
+ decrement_retry_count
25
+ @policy.wait
26
+ retry
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def time_out?
33
+ Time.now - @start_time > @policy.timeout
34
+ end
35
+
36
+ def decrement_retry_count
37
+ @policy.count -= 1
38
+ end
39
+
40
+ def retry_count_reached?
41
+ @policy.count == 0
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+ module Greenjaguar
2
+ module Strategies
3
+ class DefaultWaitStrategy < WaitStrategy
4
+ def initialize
5
+ super
6
+ @time_to_wait = 0
7
+ end
8
+
9
+ def reset_vars
10
+ end
11
+
12
+ def wait
13
+ sleep @time_to_wait
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ module Greenjaguar
2
+ module Strategies
3
+ class ExponentialBackoffStrategy < WaitStrategy
4
+ def initialize
5
+ super
6
+ @retry_interval = 0.5
7
+ @randomization_factor = 0.5
8
+ @retry_count = 0
9
+ end
10
+
11
+ def reset_vars
12
+ @retry_interval = 0.5 * convert_to(time_unit)
13
+ @randomization_factor = 0.5
14
+ end
15
+
16
+ def wait
17
+ sleep @retry_interval
18
+ @retry_count += 1
19
+ increment = (2 ** @retry_count - 1) * ([1 - @randomization_factor,
20
+ 1 + @randomization_factor][random_index])
21
+ @retry_interval += increment * convert_to(time_unit)
22
+ end
23
+
24
+ private
25
+ def random_index
26
+ rand(2)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,25 @@
1
+ module Greenjaguar
2
+ module Strategies
3
+ class FibonacciStrategy < WaitStrategy
4
+ def initialize
5
+ super
6
+ @prev_time_to_wait = 1
7
+ @time_to_wait = @prev_time_to_wait
8
+ end
9
+
10
+ def reset_vars
11
+ @prev_time_to_wait = 1 * convert_to(time_unit)
12
+ @time_to_wait = @prev_time_to_wait
13
+ end
14
+
15
+ def wait
16
+ sleep @time_to_wait
17
+ new_time = @prev_time_to_wait + @time_to_wait
18
+ @prev_time_to_wait = @time_to_wait
19
+ @time_to_wait = new_time
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+
@@ -0,0 +1,18 @@
1
+ module Greenjaguar
2
+ module Strategies
3
+ class FixedIntervalStrategy < WaitStrategy
4
+ def initialize(*args)
5
+ super
6
+ @time_to_wait = args[0]
7
+ end
8
+
9
+ def reset_vars
10
+ @time_to_wait = @time_to_wait * convert_to(time_unit)
11
+ end
12
+
13
+ def wait
14
+ sleep @time_to_wait
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Greenjaguar
2
+ module Strategies
3
+ class RandomStrategy < WaitStrategy
4
+ def initialize
5
+ super
6
+ @time_to_wait = 5
7
+ end
8
+
9
+ def reset_vars
10
+ @time_to_wait = 5 * convert_to(time_unit)
11
+ end
12
+
13
+ def wait
14
+ rand(@time_to_wait)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ module Greenjaguar
2
+ module Strategies
3
+ class WaitStrategy
4
+ attr_accessor :time_unit
5
+
6
+ def initialize(*args)
7
+ @time_unit = :sec # default value is seconds
8
+ end
9
+
10
+ def time_unit=(value)
11
+ @time_unit = value
12
+ reset_vars
13
+ end
14
+
15
+ def wait
16
+ raise "wait not implemented by subclass"
17
+ end
18
+
19
+ def reset_vars
20
+ raise "reset_vars not implemented by subclass. This method should be implemented by subclasses to init their wait time unit"
21
+ end
22
+
23
+ def convert_to(time_unit)
24
+ if time_unit == :sec
25
+ 1
26
+ else
27
+ 0.001
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module Greenjaguar
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,25 @@
1
+ require 'greenjaguar/version'
2
+ require 'greenjaguar/strategies/wait_strategy'
3
+ require 'greenjaguar/strategies/default_wait_strategy'
4
+ require 'greenjaguar/strategies/fibonacci_strategy'
5
+ require 'greenjaguar/strategies/exponential_backoff_strategy'
6
+ require 'greenjaguar/strategies/fixed_interval_strategy'
7
+ require 'greenjaguar/policy_builder'
8
+ require 'greenjaguar/retrier'
9
+
10
+ module Greenjaguar
11
+
12
+ def self.included(klass)
13
+ klass.extend(ClassMethods)
14
+ end
15
+
16
+ module ClassMethods
17
+ def build_policy(&block)
18
+ PolicyBuilder.new(&block)
19
+ end
20
+
21
+ def robust_retry(policy, &block)
22
+ Retrier.new(policy, &block)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+
3
+ module Specs
4
+ include Greenjaguar
5
+
6
+ describe Greenjaguar do
7
+ let(:class_under_test) { Class.new { include Greenjaguar } }
8
+
9
+ before do
10
+ @stub = stub_request(:get, "http://www.example.com").to_raise("some error")
11
+ end
12
+
13
+ after do
14
+ WebMock.reset!
15
+ end
16
+
17
+ it '#run should call the passed code block 4 times' do
18
+ policy = class_under_test.build_policy do
19
+ retry_times 3
20
+ end
21
+
22
+ expect do
23
+ class_under_test.robust_retry(policy) do
24
+ Net::HTTP.get_response(URI.parse("http://www.example.com"))
25
+ end
26
+ end.to raise_error
27
+ assert_requested :get, "http://www.example.com", :times => 4
28
+ end
29
+
30
+ it '#run should call the passed code block only 1 time if successful response is received' do
31
+ @stub = stub_request(:get, "http://www.example.com")
32
+
33
+ policy = class_under_test.build_policy do
34
+ retry_times 3
35
+ end
36
+
37
+ class_under_test.robust_retry(policy) do
38
+ Net::HTTP.get_response(URI.parse("http://www.example.com"))
39
+ end
40
+ assert_requested :get, "http://www.example.com", :times => 1
41
+ end
42
+
43
+ it '#run should raise the error once retrying is completed' do
44
+ policy = class_under_test.build_policy do
45
+ retry_times 3
46
+ end
47
+
48
+ expect do
49
+ class_under_test.robust_retry(policy) do
50
+ Net::HTTP.get_response(URI.parse("http://www.example.com"))
51
+ end
52
+ end.to raise_error
53
+ end
54
+
55
+ it '#run should call the passed code block 4 times according to fibonacci sequence' do
56
+ policy = class_under_test.build_policy do
57
+ retry_times 3
58
+ with_strategy :fibonacci
59
+ measure_time_in :ms
60
+ end
61
+
62
+ expect do
63
+ class_under_test.robust_retry(policy) do
64
+ Net::HTTP.get_response(URI.parse("http://www.example.com"))
65
+ end
66
+ end.to raise_error
67
+ assert_requested :get, "http://www.example.com", :times => 4
68
+ end
69
+
70
+ it '#run should call the passed code block 4 times according to fixed interval strategy' do
71
+ policy = class_under_test.build_policy do
72
+ retry_times 3
73
+ with_strategy :fixed_interval, 2
74
+ measure_time_in :ms
75
+ end
76
+
77
+ expect do
78
+ class_under_test.robust_retry(policy) do
79
+ Net::HTTP.get_response(URI.parse("http://www.example.com"))
80
+ end
81
+ end.to raise_error
82
+ assert_requested :get, "http://www.example.com", :times => 4
83
+ end
84
+
85
+ it '#run should call the passed code block 4 times according to exponential backoff sequence' do
86
+ policy = class_under_test.build_policy do
87
+ retry_times 5
88
+ with_strategy :exponential_backoff
89
+ measure_time_in :ms
90
+ end
91
+
92
+ expect do
93
+ class_under_test.robust_retry(policy) do
94
+ Net::HTTP.get_response(URI.parse("http://www.example.com"))
95
+ end
96
+ end.to raise_error
97
+ assert_requested :get, "http://www.example.com", :times => 6
98
+ end
99
+
100
+ it '#run does not call the passed code block if exception is not part of allowed exception(s)' do
101
+ @stub = stub_request(:get, "www.example.com").to_raise(RegexpError)
102
+ policy = class_under_test.build_policy do
103
+ retry_times 5
104
+ with_strategy :fibonacci
105
+ only_on_exceptions [ZeroDivisionError]
106
+ end
107
+
108
+ expect do
109
+ class_under_test.robust_retry(policy) do
110
+ Net::HTTP.get_response(URI.parse("http://www.example.com"))
111
+ end
112
+ end.to raise_error
113
+ assert_requested :get, "http://www.example.com", :times => 1
114
+ end
115
+
116
+ it '#run should call the passed code block if exception is part of allowed exception(s)' do
117
+ @stub = stub_request(:get, "http://www.example.com").to_raise(ZeroDivisionError)
118
+
119
+ policy = class_under_test.build_policy do
120
+ retry_times 10
121
+ with_strategy :fibonacci
122
+ measure_time_in :ms
123
+ only_on_exceptions [ZeroDivisionError, IOError]
124
+ end
125
+
126
+ expect do
127
+ class_under_test.robust_retry(policy) do
128
+ Net::HTTP.get_response(URI.parse("http://www.example.com"))
129
+ end
130
+ end.to raise_error
131
+ assert_requested :get, "http://www.example.com", :times => 11
132
+ end
133
+
134
+ it '#run should not raise the error if set to fail silently' do
135
+ policy = class_under_test.build_policy do
136
+ retry_times 3
137
+ fail_silently
138
+ end
139
+
140
+ class_under_test.robust_retry(policy) do
141
+ Net::HTTP.get_response(URI.parse("http://www.example.com"))
142
+ end
143
+ end
144
+
145
+ end
146
+ end
@@ -0,0 +1,4 @@
1
+ require 'pry'
2
+ require 'greenjaguar'
3
+ require 'byebug'
4
+ require 'webmock/rspec'
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: greenjaguar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Aniruddha Deshpande
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.6'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '6.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '6.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.21'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.21'
111
+ description: ''
112
+ email:
113
+ - anides84 AT hotmail DOT com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - ".ruby-version"
120
+ - ".travis.yml"
121
+ - Gemfile
122
+ - Guardfile
123
+ - LICENSE
124
+ - README.md
125
+ - Rakefile
126
+ - greenjaguar.gemspec
127
+ - lib/greenjaguar.rb
128
+ - lib/greenjaguar/policy_builder.rb
129
+ - lib/greenjaguar/retrier.rb
130
+ - lib/greenjaguar/strategies/default_wait_strategy.rb
131
+ - lib/greenjaguar/strategies/exponential_backoff_strategy.rb
132
+ - lib/greenjaguar/strategies/fibonacci_strategy.rb
133
+ - lib/greenjaguar/strategies/fixed_interval_strategy.rb
134
+ - lib/greenjaguar/strategies/random_strategy.rb
135
+ - lib/greenjaguar/strategies/wait_strategy.rb
136
+ - lib/greenjaguar/version.rb
137
+ - spec/greenjaguar_spec.rb
138
+ - spec/spec_helper.rb
139
+ homepage: https://github.com/aniruddha84/greenjaguar
140
+ licenses:
141
+ - MIT
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 2.2.3
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: Applies retry behavior to arbitrary code blocks with different policies like
163
+ fibonacci, exponential backoff, FixedInterval, etc. This basically is the 'retry'
164
+ construct on steroids.
165
+ test_files:
166
+ - spec/greenjaguar_spec.rb
167
+ - spec/spec_helper.rb