tretry 0.0.1 → 0.0.4

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
+ SHA256:
3
+ metadata.gz: 7ec5ecfe155371b1b3c9698118b3d1d01c6136125c94dc136925ae1473e234a6
4
+ data.tar.gz: 497ed8ab7b1bff0ae9f9c5025fab65b086459f6aa55b73fdfaf624a8a62ef875
5
+ SHA512:
6
+ metadata.gz: f28e16cff32efb56d911ad726f2f23d8d8aebe1ad602ca364b9321caf67fc793528afe73a828ae97c5c503163a348aa38ef3dab8c9ac18a28644be68097db052
7
+ data.tar.gz: c40a00b1dbb9afa773e438dfdef671d4a614f5da4b852266ac80d6d1e6595238d14c688c6c4586cbffd7a383568aa233f52126c9b2aa99dec712278f57d99624
data/Rakefile CHANGED
@@ -1,49 +1,23 @@
1
- # encoding: utf-8
2
-
3
- require 'rubygems'
4
- require 'bundler'
1
+ require "rubygems"
2
+ require "bundler"
5
3
  begin
6
4
  Bundler.setup(:default, :development)
7
5
  rescue Bundler::BundlerError => e
8
- $stderr.puts e.message
9
- $stderr.puts "Run `bundle install` to install missing gems"
6
+ $stderr.warn e.message
7
+ $stderr.warn "Run `bundle install` to install missing gems"
10
8
  exit e.status_code
11
9
  end
12
- require 'rake'
13
-
14
- require 'jeweler'
15
- Jeweler::Tasks.new do |gem|
16
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
- gem.name = "tretry"
18
- gem.homepage = "http://github.com/kaspernj/tretry"
19
- gem.license = "MIT"
20
- gem.summary = %Q{A library for doing retries in Ruby with timeouts, analysis of errors, waits between tries and more.}
21
- gem.description = %Q{A library for doing retries in Ruby with timeouts, analysis of errors, waits between tries and more.}
22
- gem.email = "k@spernj.org"
23
- gem.authors = ["Kasper Johansen"]
24
- # dependencies defined in Gemfile
25
- end
26
- Jeweler::RubygemsDotOrgTasks.new
10
+ require "rake"
27
11
 
28
- require 'rspec/core'
29
- require 'rspec/core/rake_task'
12
+ require "rspec/core"
13
+ require "rspec/core/rake_task"
30
14
  RSpec::Core::RakeTask.new(:spec) do |spec|
31
- spec.pattern = FileList['spec/**/*_spec.rb']
15
+ spec.pattern = FileList["spec/**/*_spec.rb"]
32
16
  end
33
17
 
34
18
  RSpec::Core::RakeTask.new(:rcov) do |spec|
35
- spec.pattern = 'spec/**/*_spec.rb'
19
+ spec.pattern = "spec/**/*_spec.rb"
36
20
  spec.rcov = true
37
21
  end
38
22
 
39
- task :default => :spec
40
-
41
- require 'rdoc/task'
42
- Rake::RDocTask.new do |rdoc|
43
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
-
45
- rdoc.rdoc_dir = 'rdoc'
46
- rdoc.title = "tretry #{version}"
47
- rdoc.rdoc_files.include('README*')
48
- rdoc.rdoc_files.include('lib/**/*.rb')
49
- end
23
+ task default: :spec
@@ -0,0 +1,22 @@
1
+ class Tretry::Result
2
+ attr_reader :error, :fails, :result
3
+
4
+ def initialize(error:, fails:, result:)
5
+ @error = error
6
+ @fails = fails
7
+ @result = result
8
+ end
9
+
10
+ def [](key)
11
+ case key
12
+ when :error
13
+ error
14
+ when :fails
15
+ fails
16
+ when :result
17
+ result
18
+ else
19
+ raise "Unknown key: #{key}"
20
+ end
21
+ end
22
+ end
data/lib/tretry.rb CHANGED
@@ -1,93 +1,128 @@
1
- #A library for doing retries in Ruby with timeouts, analysis of errors, waits between tries and more.
1
+ # A library for doing retries in Ruby with timeouts, analysis of errors, waits between tries and more.
2
2
  class Tretry
3
- #Valid keys that can be given as argument for the method 'try'.
4
- VALID_KEYS = [:tries, :timeout, :wait, :interrupt, :exit, :errors, :return_error]
5
-
3
+ autoload :Result, "#{__dir__}/tretry/result"
4
+
5
+ attr_accessor :error, :errors, :exit, :fails, :interrupt, :return_error, :timeout, :tries, :wait
6
+
6
7
  #===Runs a block of code a given amount of times until it succeeds.
7
8
  #===Examples
8
9
  # res = Tretry.try(:tries => 3) do
9
10
  # #something that often fails
10
11
  # end
11
- #
12
+ #
12
13
  # puts "Tries: '#{res[:tries]}'."
13
14
  # puts "Result: '#{res[:result}'."
14
- def self.try(args = {}, &block)
15
- #Validate given arguments and set various variables.
16
- raise "No block was given." if !block
17
- raise "Expected argument to be a hash." if !args.is_a?(Hash)
18
-
19
- args.each do |key, val|
20
- raise "Invalid key: '#{key}'." if !VALID_KEYS.include?(key)
21
- end
22
-
23
- args[:tries] = 3 if !args[:tries]
24
- tries = []
25
- error = nil
26
- res = nil
27
-
28
- args[:tries].to_i.downto(1) do |count|
29
- error = nil
30
- dobreak = false
31
-
15
+ def self.try(**args, &block)
16
+ Tretry.new(**args).try(&block)
17
+ end
18
+
19
+ def initialize(errors: nil, exit: true, interrupt: true, return_error: nil, timeout: nil, tries: 3, wait: nil)
20
+ self.errors = errors
21
+ self.exit = exit
22
+ self.fails = []
23
+ self.interrupt = interrupt
24
+ @before_retry = []
25
+ self.return_error = return_error
26
+ self.timeout = timeout
27
+ self.tries = tries
28
+ self.wait = wait
29
+ end
30
+
31
+ def before_retry(&block)
32
+ @before_retry << block
33
+ end
34
+
35
+ def try(&block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
36
+ raise "No block given." unless block
37
+
38
+ @block = block
39
+
40
+ tries.times do |count|
41
+ @count = count
42
+
43
+ unless first_try?
44
+ # Sleep for a given amount of time if the 'wait'-argument is given.
45
+ sleep(wait) if wait
46
+
47
+ call_before_retry(error: error)
48
+ self.error = nil
49
+ end
50
+
32
51
  begin
33
- if args[:timeout]
34
- #If a timeout-argument has been given, then run the code through the timeout.
35
- begin
36
- require "timeout"
37
- Timeout.timeout(args[:timeout]) do
38
- res = block.call
39
- dobreak = true
40
- break
41
- end
42
- rescue Timeout::Error => e
43
- doraise = e if count <= 1
44
- error = e
45
- sleep(args[:wait]) if args[:wait] and !doraise
46
- end
52
+ # If a timeout-argument has been given, then run the code through the timeout.
53
+ if timeout
54
+ try_with_timeout
47
55
  else
48
- #Else call block normally.
49
- res = block.call
50
- dobreak = true
51
- break
52
- end
53
- rescue Exception => e
54
- if e.class == Interrupt
55
- raise e if !args.key?(:interrupt) or args[:interrupt]
56
- elsif e.class == SystemExit
57
- raise e if !args.key?(:exit) or args[:exit]
58
- elsif count <= 1 or (args.key?(:errors) and args[:errors].index(e.class) == nil)
59
- doraise = e
60
- elsif args.key?(:errors) and args[:errors].index(e.class) != nil
61
- #given error was in the :errors-array - do nothing. Maybe later it should be logged and returned in a stats-hash or something? - knj
56
+ # Else call block normally.
57
+ @res = @block.call
58
+ @dobreak = true
62
59
  end
63
-
64
- error = e
65
-
66
- #Sleep for a given amount of time if the 'wait'-argument is given.
67
- sleep(args[:wait]) if args[:wait] and !doraise
60
+ rescue Exception => e # rubocop:disable Lint/RescueException
61
+ handle_error(e)
68
62
  end
69
-
70
- if doraise
71
- if args[:return_error]
72
- tries << {:error => error}
73
- return {
74
- :tries => tries,
75
- :error => true
76
- }
77
- else
78
- raise e
63
+
64
+ if @doraise
65
+ if return_error
66
+ fails << {error: error}
67
+
68
+ return Tretry::Result.new(
69
+ fails: fails,
70
+ error: true
71
+ )
79
72
  end
73
+
74
+ raise error
80
75
  elsif error
81
- tries << {:error => error}
76
+ fails << {error: error}
82
77
  end
83
-
84
- break if dobreak
78
+
79
+ break if @dobreak
85
80
  end
86
-
87
- return {
88
- :tries => tries,
89
- :result => res,
90
- :error => false
91
- }
81
+
82
+ Tretry::Result.new(
83
+ fails: fails,
84
+ result: @res,
85
+ error: false
86
+ )
87
+ end
88
+
89
+ private
90
+
91
+ def try_with_timeout
92
+ require "timeout"
93
+ Timeout.timeout(timeout) do
94
+ @res = @block.call
95
+ @dobreak = true
96
+ end
97
+ rescue Timeout::Error => e
98
+ handle_error(e)
99
+ end
100
+
101
+ def handle_error(error) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
102
+ if error.instance_of?(Interrupt)
103
+ raise error if interrupt
104
+ elsif error.instance_of?(SystemExit)
105
+ raise error if self.exit
106
+ elsif last_try? || (errors && !errors.include?(error.class))
107
+ @doraise = error
108
+ elsif errors&.include?(error.class) # rubocop:disable Lint/EmptyConditionalBody
109
+ # Given error was in the :errors-array - do nothing. Maybe later it should be logged and returned in a stats-hash or something? - knj
110
+ end
111
+
112
+ self.error = error
113
+ end
114
+
115
+ def call_before_retry(args)
116
+ @before_retry.each do |before_retry_block|
117
+ before_retry_block.call(args)
118
+ end
119
+ end
120
+
121
+ def last_try?
122
+ (@count + 1) >= tries
123
+ end
124
+
125
+ def first_try?
126
+ @count.zero?
92
127
  end
93
- end
128
+ end
metadata CHANGED
@@ -1,113 +1,118 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: tretry
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
6
5
  platform: ruby
7
- authors:
8
- - Kasper Johansen
6
+ authors:
7
+ - Kasper Stöckel
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
-
13
- date: 2012-08-30 00:00:00 +02:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
11
+ date: 2022-05-10 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: 2.3.13
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.3.13
27
+ - !ruby/object:Gem::Dependency
17
28
  name: rspec
18
- requirement: &id001 !ruby/object:Gem::Requirement
19
- none: false
20
- requirements:
21
- - - ~>
22
- - !ruby/object:Gem::Version
23
- version: 2.8.0
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 3.11.0
24
34
  type: :development
25
35
  prerelease: false
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: rdoc
29
- requirement: &id002 !ruby/object:Gem::Requirement
30
- none: false
31
- requirements:
32
- - - ~>
33
- - !ruby/object:Gem::Version
34
- version: "3.12"
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 3.11.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
35
48
  type: :development
36
49
  prerelease: false
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: bundler
40
- requirement: &id003 !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
43
52
  - - ">="
44
- - !ruby/object:Gem::Version
45
- version: 1.0.0
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop-performance
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
46
62
  type: :development
47
63
  prerelease: false
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
50
- name: jeweler
51
- requirement: &id004 !ruby/object:Gem::Requirement
52
- none: false
53
- requirements:
54
- - - ~>
55
- - !ruby/object:Gem::Version
56
- version: 1.8.4
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
57
76
  type: :development
58
77
  prerelease: false
59
- version_requirements: *id004
60
- description: A library for doing retries in Ruby with timeouts, analysis of errors, waits between tries and more.
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: A library for doing retries in Ruby with timeouts, analysis of errors,
84
+ waits between tries and more.
61
85
  email: k@spernj.org
62
86
  executables: []
63
-
64
87
  extensions: []
65
-
66
- extra_rdoc_files:
67
- - LICENSE.txt
68
- - README.rdoc
69
- files:
70
- - .document
71
- - .rspec
72
- - Gemfile
73
- - Gemfile.lock
74
- - LICENSE.txt
75
- - README.rdoc
88
+ extra_rdoc_files: []
89
+ files:
76
90
  - Rakefile
77
- - VERSION
78
91
  - lib/tretry.rb
79
- - spec/spec_helper.rb
80
- - spec/tretry_spec.rb
81
- has_rdoc: true
92
+ - lib/tretry/result.rb
82
93
  homepage: http://github.com/kaspernj/tretry
83
- licenses:
94
+ licenses:
84
95
  - MIT
96
+ metadata:
97
+ rubygems_mfa_required: 'true'
85
98
  post_install_message:
86
99
  rdoc_options: []
87
-
88
- require_paths:
100
+ require_paths:
89
101
  - lib
90
- required_ruby_version: !ruby/object:Gem::Requirement
91
- none: false
92
- requirements:
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
93
104
  - - ">="
94
- - !ruby/object:Gem::Version
95
- hash: 3966091872588483067
96
- segments:
97
- - 0
98
- version: "0"
99
- required_rubygems_version: !ruby/object:Gem::Requirement
100
- none: false
101
- requirements:
105
+ - !ruby/object:Gem::Version
106
+ version: '2.6'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
102
109
  - - ">="
103
- - !ruby/object:Gem::Version
104
- version: "0"
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
105
112
  requirements: []
106
-
107
- rubyforge_project:
108
- rubygems_version: 1.6.2
113
+ rubygems_version: 3.0.3.1
109
114
  signing_key:
110
- specification_version: 3
111
- summary: A library for doing retries in Ruby with timeouts, analysis of errors, waits between tries and more.
115
+ specification_version: 4
116
+ summary: A library for doing retries in Ruby with timeouts, analysis of errors, waits
117
+ between tries and more.
112
118
  test_files: []
113
-
data/.document DELETED
@@ -1,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- LICENSE.txt
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --color
data/Gemfile DELETED
@@ -1,13 +0,0 @@
1
- source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
-
6
- # Add dependencies to develop your gem here.
7
- # Include everything needed to run rake, tests, features, etc.
8
- group :development do
9
- gem "rspec", "~> 2.8.0"
10
- gem "rdoc", "~> 3.12"
11
- gem "bundler", ">= 1.0.0"
12
- gem "jeweler", "~> 1.8.4"
13
- end
data/Gemfile.lock DELETED
@@ -1,31 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- diff-lcs (1.1.3)
5
- git (1.2.5)
6
- jeweler (1.8.4)
7
- bundler (~> 1.0)
8
- git (>= 1.2.5)
9
- rake
10
- rdoc
11
- json (1.7.5)
12
- rake (0.9.2.2)
13
- rdoc (3.12)
14
- json (~> 1.4)
15
- rspec (2.8.0)
16
- rspec-core (~> 2.8.0)
17
- rspec-expectations (~> 2.8.0)
18
- rspec-mocks (~> 2.8.0)
19
- rspec-core (2.8.0)
20
- rspec-expectations (2.8.0)
21
- diff-lcs (~> 1.1.2)
22
- rspec-mocks (2.8.0)
23
-
24
- PLATFORMS
25
- ruby
26
-
27
- DEPENDENCIES
28
- bundler (>= 1.0.0)
29
- jeweler (~> 1.8.4)
30
- rdoc (~> 3.12)
31
- rspec (~> 2.8.0)
data/LICENSE.txt DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2012 Kasper Johansen
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc DELETED
@@ -1,19 +0,0 @@
1
- = tretry
2
-
3
- Description goes here.
4
-
5
- == Contributing to tretry
6
-
7
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
- * Fork the project.
10
- * Start a feature/bugfix branch.
11
- * Commit and push until you are happy with your contribution.
12
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
-
15
- == Copyright
16
-
17
- Copyright (c) 2012 Kasper Johansen. See LICENSE.txt for
18
- further details.
19
-
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.1
data/spec/spec_helper.rb DELETED
@@ -1,12 +0,0 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- require 'rspec'
4
- require 'tretry'
5
-
6
- # Requires supporting files with custom matchers and macros, etc,
7
- # in ./support/ and its subdirectories.
8
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
-
10
- RSpec.configure do |config|
11
-
12
- end
data/spec/tretry_spec.rb DELETED
@@ -1,47 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe "Tretry" do
4
- it "should be able to run blocks" do
5
- try = 0
6
- res = Tretry.try(:tries => 5) do
7
- try += 1
8
- raise "Test #{try}" if try < 5
9
- "kasper"
10
- end
11
-
12
- raise "Expected error to be false but it wasnt: '#{res[:error]}'." if res[:error] != false
13
- raise "Expected result to be 'kasper' but it wasnt: '#{res[:result]}'." if res[:result] != "kasper"
14
- end
15
-
16
- it "should be able to do waits between tries" do
17
- try = 0
18
- time_start = Time.now.to_f
19
- res = Tretry.try(:tries => 5, :wait => 0.1) do
20
- try += 1
21
- raise "Test #{try}" if try < 5
22
- "kasper"
23
- end
24
-
25
- time_end = Time.now.to_f
26
- time_elap = time_end - time_start
27
-
28
- raise "Expected time to be more than 0.4 sec but it wasnt: '#{time_elap}'." if time_elap < 0.4
29
- end
30
-
31
- it "should be able to do timeouts with tries" do
32
- try = 0
33
- res = Tretry.try(:tries => 5, :timeout => 0.1) do
34
- try += 1
35
- sleep 0.5 if try < 5
36
- "kasper"
37
- end
38
-
39
- raise "Expected error to be false but it wasnt: '#{res[:error]}'." if res[:error] != false
40
- raise "Expected result to be 'kasper' but it wasnt: '#{res[:result]}'." if res[:result] != "kasper"
41
- raise "Expected number of errors to be 4 but it wasnt: '#{res[:tries].length}'." if res[:tries].length != 4
42
-
43
- res[:tries].each do |err|
44
- raise "Expected error to be 'Timeout::Error' but it wasnt: '#{err[:error].class.name}'." if !err[:error].is_a?(Timeout::Error)
45
- end
46
- end
47
- end