wait 0.4.1 → 0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  class Wait
2
2
  class BaseCounter
3
- attr_reader :attempt
3
+ attr_accessor :logger
4
+ attr_reader :attempt
4
5
 
5
- def initialize(logger, total)
6
- @logger = logger
6
+ def initialize(total)
7
7
  # Attempt to prevent causing an infinite loop by being very strict about
8
8
  # the value passed.
9
9
  unless total.is_a?(Fixnum) and total > 0
@@ -11,7 +11,6 @@ class Wait
11
11
  end
12
12
 
13
13
  @total = total
14
- reset
15
14
  end
16
15
 
17
16
  # Called before all attempts to reset the counter.
@@ -32,7 +31,9 @@ class Wait
32
31
 
33
32
  # Logs the current attempt count.
34
33
  def log
35
- @logger.debug "[Counter] attempt #{self}"
34
+ return if @logger.nil?
35
+
36
+ @logger.debug("Counter") { "attempt #{self}" }
36
37
  end
37
38
 
38
39
  # Returns a string representation of the current count.
@@ -1,19 +1,22 @@
1
1
  class Wait
2
2
  class BaseDelayer
3
- def initialize(logger, initial_delay)
4
- @logger = logger
5
- @delay = initial_delay
3
+ attr_accessor :logger
4
+
5
+ def initialize(delay)
6
+ @delay = delay
6
7
  end
7
8
 
8
9
  # Called before a reattempt to sleep a certain about of time.
9
10
  def sleep
10
- log_delay
11
+ log
11
12
  Kernel.sleep(@delay)
12
13
  end
13
14
 
14
15
  # Logs how long the delay is.
15
- def log_delay
16
- @logger.debug "[Delayer] delaying for #{self}"
16
+ def log
17
+ return if @logger.nil?
18
+
19
+ @logger.debug("Delayer") { "delaying for #{self}" }
17
20
  end
18
21
 
19
22
  # Returns a string representation of the delay.
@@ -2,15 +2,21 @@ require "timeout"
2
2
  require "logger"
3
3
  require "forwardable"
4
4
 
5
- require File.expand_path("../loggers/base", __FILE__)
6
- require File.expand_path("../loggers/debug", __FILE__)
7
- require File.expand_path("../counters/base", __FILE__)
8
- require File.expand_path("../delayers/base", __FILE__)
9
- require File.expand_path("../delayers/regular", __FILE__)
10
- require File.expand_path("../delayers/exponential", __FILE__)
11
- require File.expand_path("../testers/base", __FILE__)
12
- require File.expand_path("../testers/passive", __FILE__)
13
- require File.expand_path("../testers/truthy", __FILE__)
14
- require File.expand_path("../rescuers/base", __FILE__)
15
- require File.expand_path("../raisers/base", __FILE__)
16
- require File.expand_path("../raisers/passive", __FILE__)
5
+ paths = %w(
6
+ version
7
+ loggers/base
8
+ loggers/debug
9
+ counters/base
10
+ delayers/base
11
+ delayers/regular
12
+ delayers/exponential
13
+ testers/base
14
+ testers/passive
15
+ testers/truthy
16
+ rescuers/base
17
+ raisers/base
18
+ raisers/passive
19
+ raisers/signal
20
+ )
21
+
22
+ paths.each { |path| require File.expand_path("../#{path}", __FILE__) }
@@ -2,12 +2,12 @@ class Wait
2
2
  class BaseLogger
3
3
  extend Forwardable
4
4
 
5
- attr_reader :logger
5
+ attr_reader :logger
6
6
  def_delegators :logger, :fatal,
7
- :error,
8
- :warn,
9
- :info,
10
- :debug
7
+ :error,
8
+ :warn,
9
+ :info,
10
+ :debug
11
11
 
12
12
  def initialize
13
13
  @logger = ::Logger.new(STDOUT)
@@ -20,13 +20,13 @@ class Wait
20
20
  end
21
21
 
22
22
  def formatter
23
- proc do |severity, datetime, program_name, message|
24
- [severity.ljust(5), message].join(" ") + "\n"
23
+ proc do |severity, datetime, caller, message|
24
+ "#{severity.ljust(5)} #{"[#{caller}]".ljust(9)} #{message}\n"
25
25
  end
26
26
  end
27
27
 
28
- def backtrace(backtrace)
29
- backtrace.map { |line| (" " * 25) + line }.join("\n")
28
+ def indent(lines, spaces = 25)
29
+ lines.map { |line| (" " * spaces) + line }.join("\n")
30
30
  end
31
31
  end # Logger
32
32
  end # Wait
@@ -1,18 +1,18 @@
1
1
  class Wait
2
2
  class BaseRaiser
3
- def initialize(logger, exception)
4
- @logger = logger
5
- @exception = exception
6
- log
7
- end
3
+ attr_accessor :logger
8
4
 
9
5
  # Returns +true+ if an exception ought to be raised.
10
- def raise?
11
- false
6
+ def raise?(exception)
7
+ false.tap do |raising|
8
+ log(exception, raising)
9
+ end
12
10
  end
13
11
 
14
- def log
15
- @logger.debug "[Raiser] raise? #{@exception.class.name}: #{raise?}"
12
+ def log(exception, raising)
13
+ return if @logger.nil?
14
+
15
+ @logger.debug("Raiser") { "#{"not " unless raising}raising: #{exception.class.name}" }
16
16
  end
17
17
  end # BaseRaiser
18
18
  end # Wait
@@ -0,0 +1,14 @@
1
+ class Wait
2
+ class SignalRaiser < BaseRaiser
3
+ def raise?(exception)
4
+ signal_exception?(exception.class).tap do |raising|
5
+ log(exception, raising)
6
+ end
7
+ end
8
+
9
+ # Returns +true+ if an exception raised is a signal exception.
10
+ def signal_exception?(klass)
11
+ [SignalException, Interrupt, NoMemoryError, SystemExit].include?(klass)
12
+ end
13
+ end # SignalRaiser
14
+ end # Wait
@@ -1,15 +1,23 @@
1
1
  class Wait
2
2
  class BaseRescuer
3
- attr_reader :exceptions
3
+ attr_accessor :logger
4
+ attr_reader :exceptions
4
5
 
5
- def initialize(logger, *exceptions)
6
- @logger = logger
6
+ def initialize(exceptions)
7
7
  @exceptions = Array(exceptions).flatten
8
8
  end
9
9
 
10
10
  # Logs an exception.
11
11
  def log(exception)
12
- @logger.debug "[Rescuer] rescued: #{exception.class.name}: #{exception.message}\n#{@logger.backtrace(exception.backtrace)}"
12
+ return if @logger.nil?
13
+
14
+ klass = exception.class.name
15
+ # We can omit the message if it's identical to the class name.
16
+ message = exception.message unless exception.message == klass
17
+ # Indent the exception so it stands apart from the rest of the messages.
18
+ backtrace = @logger.indent(exception.backtrace)
19
+
20
+ @logger.debug("Rescuer") { "rescued: #{klass}#{": #{message}" if message}\n#{backtrace}" }
13
21
  end
14
22
  end # BaseRescuer
15
23
  end # Wait
@@ -1,18 +1,18 @@
1
1
  class Wait
2
2
  class BaseTester
3
- def initialize(logger, result)
4
- @logger = logger
5
- @result = result
6
- log
7
- end
3
+ attr_accessor :logger
8
4
 
9
5
  # Returns +true+ if a result if valid.
10
- def valid?
6
+ def valid?(result)
7
+ log(result)
8
+
11
9
  true
12
10
  end
13
11
 
14
- def log
15
- @logger.debug "[Tester] result: #{@result.inspect}"
12
+ def log(result)
13
+ return if @logger.nil?
14
+
15
+ @logger.debug("Tester") { "result: #{result.inspect}" }
16
16
  end
17
17
  end # BaseTester
18
18
  end # Wait
@@ -1,7 +1,9 @@
1
1
  class Wait
2
2
  class TruthyTester < BaseTester
3
- def valid?
4
- not (@result.nil? or @result == false)
3
+ def valid?(result)
4
+ log(result)
5
+
6
+ not (result.nil? or result == false)
5
7
  end
6
8
  end # TruthyTester
7
9
  end # Wait
@@ -0,0 +1,3 @@
1
+ class Wait
2
+ VERSION = "0.5"
3
+ end # Wait
@@ -9,7 +9,7 @@ class Wait
9
9
  :delayer => RegularDelayer,
10
10
  :rescuer => BaseRescuer,
11
11
  :tester => TruthyTester,
12
- :raiser => PassiveRaiser,
12
+ :raiser => SignalRaiser,
13
13
  :logger => BaseLogger
14
14
  }
15
15
 
@@ -43,20 +43,26 @@ class Wait
43
43
  # Strategy used to test the result. Default is Wait::TruthyTester.
44
44
  # [:raiser]
45
45
  # Strategy used to raise specific exceptions. Default is
46
- # Wait::PassiveRaiser.
46
+ # Wait::SignalRaiser.
47
47
  #
48
48
  def initialize(options = {})
49
- debug = options[:debug] || false
50
- @logger = (options[:logger] || (debug ? DebugLogger : DEFAULT[:logger])).new
51
- attempts = options[:attempts] || DEFAULT[:attempts]
52
- @counter = (options[:counter] || DEFAULT[:counter]).new(@logger, attempts)
53
- @timeout = options[:timeout] || DEFAULT[:timeout]
54
- delay = options[:delay] || DEFAULT[:delay]
55
- @delayer = (options[:delayer] || DEFAULT[:delayer]).new(@logger, delay)
56
- exceptions = options[:rescue]
57
- @rescuer = (options[:rescuer] || DEFAULT[:rescuer]).new(@logger, exceptions)
58
- @tester = options[:tester] || DEFAULT[:tester]
59
- @raiser = options[:raiser] || DEFAULT[:raiser]
49
+ # Assign defaults.
50
+ debug = options[:debug] || false
51
+ @logger = options[:logger] || (debug ? DebugLogger : DEFAULT[:logger]).new
52
+ attempts = options[:attempts] || DEFAULT[:attempts]
53
+ @counter = options[:counter] || DEFAULT[:counter].new(attempts)
54
+ @timeout = options[:timeout] || DEFAULT[:timeout]
55
+ delay = options[:delay] || DEFAULT[:delay]
56
+ @delayer = options[:delayer] || DEFAULT[:delayer].new(delay)
57
+ exceptions = options[:rescue]
58
+ @rescuer = options[:rescuer] || DEFAULT[:rescuer].new(exceptions)
59
+ @tester = options[:tester] || DEFAULT[:tester].new
60
+ @raiser = options[:raiser] || DEFAULT[:raiser].new
61
+
62
+ # Assign the logger to each of the strategies.
63
+ [@counter, @delayer, @rescuer, @tester, @raiser].each do |strategy|
64
+ strategy.logger = @logger if strategy.respond_to?(:logger=)
65
+ end
60
66
  end
61
67
 
62
68
  # == Description
@@ -74,12 +80,12 @@ class Wait
74
80
  # # => #<Wait>
75
81
  # wait.until { Time.now.sec.even? }
76
82
  # # [Counter] attempt 1/5
77
- # # [Tester] result: false
78
- # # [Rescuer] rescued: Wait::InvalidResult: Wait::InvalidResult
79
- # # [Raiser] raise? Wait::InvalidResult: false
83
+ # # [Tester] result: false
84
+ # # [Rescuer] rescued: Wait::ResultInvalid
85
+ # # [Raiser] not raising: Wait::ResultInvalid
80
86
  # # [Delayer] delaying for 1s
81
87
  # # [Counter] attempt 2/5
82
- # # [Tester] result: true
88
+ # # [Tester] result: true
83
89
  # # => true
84
90
  #
85
91
  # If you wish to handle an exception by attempting the block again, pass one
@@ -95,16 +101,16 @@ class Wait
95
101
  # end
96
102
  # end
97
103
  # # [Counter] attempt 1/5
98
- # # [Tester] result: nil
99
- # # [Rescuer] rescued: Wait::InvalidResult: Wait::InvalidResult
100
- # # [Raiser] raise? Wait::InvalidResult: false
104
+ # # [Tester] result: nil
105
+ # # [Rescuer] rescued: Wait::ResultInvalid
106
+ # # [Raiser] not raising: Wait::ResultInvalid
101
107
  # # [Delayer] delaying for 1s
102
108
  # # [Counter] attempt 2/5
103
- # # [Rescuer] rescued: RuntimeError: RuntimeError
104
- # # [Raiser] raise? RuntimeError: false
109
+ # # [Rescuer] rescued: RuntimeError
110
+ # # [Raiser] not raising: RuntimeError
105
111
  # # [Delayer] delaying for 1s
106
112
  # # [Counter] attempt 3/5
107
- # # [Tester] result: "foo"
113
+ # # [Tester] result: "foo"
108
114
  # # => "foo"
109
115
  #
110
116
  # == Returns
@@ -127,14 +133,12 @@ class Wait
127
133
  yield(@counter.attempt)
128
134
  end
129
135
  # Raise an exception unless the result is valid.
130
- tester = @tester.new(@logger, result)
131
- tester.valid? ? result : raise(InvalidResult)
132
- rescue TimeoutError, InvalidResult, *@rescuer.exceptions => exception
136
+ @tester.valid?(result) ? result : raise(ResultInvalid)
137
+ rescue TimeoutError, ResultInvalid, *@rescuer.exceptions => exception
133
138
  # Log the exception.
134
139
  @rescuer.log(exception)
135
140
  # Raise the exception if it ought to be.
136
- raiser = @raiser.new(@logger, exception)
137
- raise(exception) if raiser.raise?
141
+ raise(exception) if @raiser.raise?(exception)
138
142
  # Raise the exception if this was the last attempt.
139
143
  raise(exception) if @counter.last_attempt?
140
144
  # Sleep before the next attempt.
@@ -148,5 +152,5 @@ class Wait
148
152
  class TimeoutError < Timeout::Error; end
149
153
 
150
154
  # Raised when a block returns an invalid result.
151
- class InvalidResult < RuntimeError; end
155
+ class ResultInvalid < RuntimeError; end
152
156
  end #Wait
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wait
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: '0.5'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -26,10 +26,12 @@ files:
26
26
  - lib/loggers/debug.rb
27
27
  - lib/raisers/base.rb
28
28
  - lib/raisers/passive.rb
29
+ - lib/raisers/signal.rb
29
30
  - lib/rescuers/base.rb
30
31
  - lib/testers/base.rb
31
32
  - lib/testers/passive.rb
32
33
  - lib/testers/truthy.rb
34
+ - lib/version.rb
33
35
  - lib/wait.rb
34
36
  homepage: http://github.com/paperlesspost/wait
35
37
  licenses: []