waiting 0.3.0 → 1.0.0
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.
- checksums.yaml +5 -13
- data/.rubocop.yml +3 -0
- data/Guardfile +5 -0
- data/README.md +69 -18
- data/lib/waiting.rb +87 -56
- data/lib/waiting/timed_out_error.rb +6 -5
- data/lib/waiting/version.rb +4 -2
- data/lib/waiting/waiter.rb +97 -24
- data/waiting.gemspec +6 -3
- metadata +59 -15
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZWZjZWEyZDQ5M2Q3ZTJkODZmNmZjZGM1OGU4MmIyNGFjOWE0MzA0Zg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b08f089788fa4aa60a91cfc69b2a680a35f20f22
|
4
|
+
data.tar.gz: 72039eb831a615731eb8f45047b629df86d45ae4
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ODRjYjA4Y2NjMjcwNjE0MjNkNWFmZjU2MzBkZjVhYWI5M2ZhZGEzZWNmYWIw
|
11
|
-
ZDI5NGJkZDg3MjRkMzgxNTIyODNjMWI0MDlkZjgwNjVmMTg1ZmM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NzZiMWNkODNkZDdjMTQxNDY5MDY4ZTdiZTM5ZDA1ZmUxMzU1ZjMyZTYzNzgz
|
14
|
-
NGI3MjRiYzY2MzI3MTYyYzUxNjM4NmFhYWMxNTc0ZGM2YWU4NTg3MDI0NDcy
|
15
|
-
MzgyMjhiMjYwY2I4NGNiMTljZmE1NWZlZTFiZGNmYzI1YjA3ZDM=
|
6
|
+
metadata.gz: ea6d32881afd57b5f9924d012a93535d7a6e9598f51a6d79affef040b6868e6adcfbc640f57d67b9b6fc836b20ab4198d9c233e963c180bc567fc974a12ae504
|
7
|
+
data.tar.gz: dcb1edb32ce17edc4798e413c68b1a15d7f20f11d7171e183b78e9d668c5395e8e91b2cd0813756b921780978fccf11cd7149bce07a9529434a2e03cec6ad1a7
|
data/.rubocop.yml
ADDED
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -25,36 +25,87 @@ Or install it yourself as:
|
|
25
25
|
```ruby
|
26
26
|
require 'waiting'
|
27
27
|
|
28
|
-
# optional
|
29
|
-
Waiting.default_max_attempts = max_attempts # defaults to 60
|
30
|
-
Waiting.default_interval = interval # seconds, defaults to 5
|
31
28
|
|
32
|
-
#
|
29
|
+
# Optionally set defaults.
|
30
|
+
#
|
31
|
+
Waiting.exp_base = exp_base # defaults to 1
|
32
|
+
Waiting.interval = interval # defaults to 5
|
33
|
+
Waiting.max_attempts = max_attempts # defaults to 60
|
34
|
+
Waiting.max_interval = max_interval # defaults to nil
|
35
|
+
|
36
|
+
|
37
|
+
# Will poll every interval, max_attempts times until something is true
|
38
|
+
#
|
33
39
|
Waiting.wait do |waiter|
|
34
40
|
waiter.done if something
|
35
41
|
end
|
36
42
|
|
37
|
-
|
38
|
-
|
43
|
+
|
44
|
+
# Override the defaults here
|
45
|
+
#
|
46
|
+
Waiting.wait(exp_base: exp_base,
|
47
|
+
interval: interval,
|
48
|
+
max_attempts: max_attempts,
|
49
|
+
max_interval: max_interval
|
50
|
+
) do |waiter|
|
39
51
|
waiter.done if something
|
40
52
|
end
|
41
53
|
|
42
|
-
|
43
|
-
#
|
44
|
-
#
|
45
|
-
Waiting.
|
54
|
+
|
55
|
+
# Or make an instance of Waiting to pass around
|
56
|
+
#
|
57
|
+
waiting = Waiting.new(exp_base: exp_base,
|
58
|
+
interval: interval,
|
59
|
+
max_attempts: max_attempts,
|
60
|
+
max_interval: max_interval
|
61
|
+
) do |waiter|
|
46
62
|
waiter.done if something
|
47
63
|
end
|
48
64
|
|
49
|
-
# or specify it as a default
|
50
|
-
Waiting.default_exp_base = exp_base # exponential backoff base, defaults to 1
|
51
65
|
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
66
|
+
# And get it to wait
|
67
|
+
#
|
68
|
+
waiting.wait
|
69
|
+
|
70
|
+
|
71
|
+
# Or overide any parameters here again
|
72
|
+
#
|
73
|
+
waiting.wait(exp_base: exp_base,
|
74
|
+
interval: interval,
|
75
|
+
max_attempts: max_attempts,
|
76
|
+
max_interval: max_interval
|
77
|
+
) do |waiter|
|
78
|
+
waiter.done if something
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
# Access the wait parameters during the wait
|
83
|
+
#
|
84
|
+
waiting.wait do |waiter|
|
85
|
+
puts "attempts: #{waiter.attempts}"
|
86
|
+
puts "exp_base: #{waiter.exp_base}"
|
87
|
+
puts "interval: #{waiter.interval}"
|
88
|
+
puts "max_attempts: #{waiter.max_attempts}"
|
89
|
+
puts "max_interval: #{waiter.max_interval}"
|
90
|
+
waiter.done if something
|
91
|
+
end
|
92
|
+
# =>
|
93
|
+
# attempts: 0
|
94
|
+
# exp_base: 1
|
95
|
+
# interval: 5
|
96
|
+
# max_attempts: 60
|
97
|
+
# max_interval: nil
|
98
|
+
|
99
|
+
|
100
|
+
# Leverage exp base for exponential back off
|
101
|
+
#
|
102
|
+
# Will wait for: 1, 2, 4, 8, 16, 16, 16...
|
103
|
+
#
|
104
|
+
waiting.wait(exp_base: 2,
|
105
|
+
interval: 1,
|
106
|
+
max_attempts: 16
|
107
|
+
) do |waiter|
|
108
|
+
waiter.done if something
|
58
109
|
end
|
59
110
|
```
|
60
111
|
|
data/lib/waiting.rb
CHANGED
@@ -1,72 +1,103 @@
|
|
1
|
-
require 'waiting/timed_out_error'
|
2
1
|
require 'waiting/waiter'
|
3
|
-
require 'waiting/version'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
# Waits for things so you don't have to
|
4
|
+
#
|
5
|
+
class Waiting
|
6
|
+
# @param interval [Numeric] Polling interval in seconds.
|
7
|
+
# @param max_attempts [Numeric] Number of attempts before timing out.
|
8
|
+
# @param exp_base [Numeric] Increases the interval by the power of attempts.
|
9
|
+
# @param max_interval [Numeric] Interval limit for exponential backoff.
|
10
|
+
#
|
11
|
+
# @yield Block to check if the wait is over.
|
12
|
+
# @yieldparam waiter [Waiting::Waiter] call +#done+ if the wait is over
|
13
|
+
#
|
14
|
+
def initialize(exp_base: self.class.default_exp_base,
|
15
|
+
interval: self.class.default_interval,
|
16
|
+
max_attempts: self.class.default_max_attempts,
|
17
|
+
max_interval: self.class.default_max_interval,
|
18
|
+
&block)
|
11
19
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
20
|
+
@exp_base = exp_base
|
21
|
+
@interval = interval
|
22
|
+
@max_attempts = max_attempts
|
23
|
+
@max_interval = max_interval
|
17
24
|
|
18
|
-
|
19
|
-
# @return [Float] the base for exponential backoff
|
20
|
-
def self.default_exp_base
|
21
|
-
@@default_exp_base ||= 1
|
25
|
+
@block = block
|
22
26
|
end
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
class << self
|
29
|
+
# The default exp base
|
30
|
+
#
|
31
|
+
# @return [Numeric]
|
32
|
+
#
|
33
|
+
attr_accessor :default_exp_base
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
+
# The default interval
|
36
|
+
#
|
37
|
+
# @return [Numeric]
|
38
|
+
#
|
39
|
+
attr_accessor :default_interval
|
35
40
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
+
# The default max attempts
|
42
|
+
#
|
43
|
+
# @return [Numeric]
|
44
|
+
#
|
45
|
+
attr_accessor :default_max_attempts
|
41
46
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
exp_base = opts.fetch(:exp_base) { default_exp_base }
|
49
|
-
max_attempts = opts.fetch(:max_attempts) { default_max_attempts }
|
47
|
+
# The default max interval
|
48
|
+
#
|
49
|
+
# @return [Numeric]
|
50
|
+
#
|
51
|
+
attr_accessor :default_max_interval
|
52
|
+
end
|
50
53
|
|
51
|
-
|
54
|
+
self.default_exp_base = 1
|
55
|
+
self.default_interval = 5
|
56
|
+
self.default_max_attempts = 60
|
57
|
+
self.default_max_interval = nil
|
52
58
|
|
53
|
-
|
59
|
+
# @param interval [Numeric] Polling interval in seconds.
|
60
|
+
# @param max_attempts [Numeric] Number of attempts before timing out.
|
61
|
+
# @param exp_base [Numeric] Increases the interval by the power of attempts.
|
62
|
+
# @param max_interval [Numeric] Interval limit for exponential backoff.
|
63
|
+
#
|
64
|
+
# @yield Block to check if the wait is over.
|
65
|
+
# @yieldparam waiter [Waiting::Waiter] call +#done+ if the wait is over
|
66
|
+
#
|
67
|
+
def wait(exp_base: @exp_base,
|
68
|
+
interval: @interval,
|
69
|
+
max_attempts: @max_attempts,
|
70
|
+
max_interval: @max_interval,
|
71
|
+
&block)
|
54
72
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
73
|
+
Waiter.new(
|
74
|
+
exp_base: exp_base,
|
75
|
+
interval: interval,
|
76
|
+
max_attempts: max_attempts,
|
77
|
+
max_interval: max_interval
|
78
|
+
).wait(&(block || @block))
|
79
|
+
end
|
59
80
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
81
|
+
# @see +#wait+
|
82
|
+
#
|
83
|
+
# @param interval [Numeric] Polling interval in seconds.
|
84
|
+
# @param max_attempts [Numeric] Number of attempts before timing out.
|
85
|
+
# @param exp_base [Numeric] Increases the interval by the power of attempts.
|
86
|
+
# @param max_interval [Numeric] Interval limit for exponential backoff.
|
87
|
+
#
|
88
|
+
# @yield Block to check if the wait is over.
|
89
|
+
# @yieldparam waiter [Waiting::Waiter] call +#done+ if the wait is over
|
90
|
+
#
|
91
|
+
def self.wait(exp_base: default_exp_base,
|
92
|
+
interval: default_interval,
|
93
|
+
max_attempts: default_max_attempts,
|
94
|
+
max_interval: default_max_interval,
|
95
|
+
&block)
|
64
96
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
97
|
+
new(exp_base: exp_base,
|
98
|
+
interval: interval,
|
99
|
+
max_attempts: max_attempts,
|
100
|
+
max_interval: max_interval,
|
101
|
+
&block).wait
|
70
102
|
end
|
71
|
-
|
72
103
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
1
|
+
class Waiting
|
2
|
+
# Raised when the wait times out
|
3
|
+
#
|
4
|
+
class TimedOutError < StandardError
|
5
|
+
end
|
6
|
+
end
|
data/lib/waiting/version.rb
CHANGED
data/lib/waiting/waiter.rb
CHANGED
@@ -1,24 +1,97 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
1
|
+
require 'waiting/timed_out_error'
|
2
|
+
|
3
|
+
class Waiting
|
4
|
+
# The class that patiently waits
|
5
|
+
#
|
6
|
+
class Waiter
|
7
|
+
# The current attempt number
|
8
|
+
#
|
9
|
+
# @return [Integer]
|
10
|
+
#
|
11
|
+
attr_reader :attempts
|
12
|
+
|
13
|
+
# The exp base
|
14
|
+
#
|
15
|
+
# @return [Numeric]
|
16
|
+
#
|
17
|
+
attr_accessor :exp_base
|
18
|
+
|
19
|
+
# The interval
|
20
|
+
#
|
21
|
+
# @return [Numeric]
|
22
|
+
#
|
23
|
+
attr_accessor :interval
|
24
|
+
|
25
|
+
# The max attempts
|
26
|
+
#
|
27
|
+
# @return [Numeric]
|
28
|
+
#
|
29
|
+
attr_accessor :max_attempts
|
30
|
+
|
31
|
+
# The max interval
|
32
|
+
#
|
33
|
+
# @return [Numeric]
|
34
|
+
#
|
35
|
+
attr_accessor :max_interval
|
36
|
+
|
37
|
+
# @param interval [Numeric] Polling interval in seconds.
|
38
|
+
# @param max_attempts [Numeric] Number of attempts before timing out.
|
39
|
+
# @param exp_base [Numeric] Increases the interval by the power of attempts.
|
40
|
+
# @param max_interval [Numeric] Interval limit for exponential backoff.
|
41
|
+
#
|
42
|
+
# @yield Block to check if the wait is over.
|
43
|
+
# @yieldparam waiter [Waiting::Waiter] call +#done+ if the wait is over
|
44
|
+
#
|
45
|
+
def initialize(exp_base: Waiting.default_exp_base,
|
46
|
+
interval: Waiting.interval,
|
47
|
+
max_attempts: Waiting.max_attempts,
|
48
|
+
max_interval: Waiting.max_interval)
|
49
|
+
|
50
|
+
@exp_base = exp_base
|
51
|
+
@interval = interval
|
52
|
+
@max_attempts = max_attempts
|
53
|
+
@max_interval = max_interval
|
54
|
+
|
55
|
+
@done = false
|
56
|
+
@attempts = 0
|
57
|
+
end
|
58
|
+
|
59
|
+
# Mark the waiter as done
|
60
|
+
#
|
61
|
+
def done
|
62
|
+
@done = true
|
63
|
+
end
|
64
|
+
|
65
|
+
# Is the waiter done?
|
66
|
+
#
|
67
|
+
# @return [Boolean] if the waiter is done
|
68
|
+
#
|
69
|
+
def done?
|
70
|
+
@done
|
71
|
+
end
|
72
|
+
|
73
|
+
# Waits for +#done+ to be called
|
74
|
+
#
|
75
|
+
# @raise [Waiting::TimedOutError] if +#done+ is not called in time
|
76
|
+
#
|
77
|
+
def wait
|
78
|
+
loop do
|
79
|
+
if @attempts >= max_attempts
|
80
|
+
raise Waiting::TimedOutError,
|
81
|
+
"Timed out after #{interval * max_attempts}s"
|
82
|
+
end
|
83
|
+
|
84
|
+
yield(self)
|
85
|
+
break if done?
|
86
|
+
wait_once
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def wait_once
|
93
|
+
sleep [exp_base**attempts * interval, max_interval].compact.min
|
94
|
+
@attempts += 1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/waiting.gemspec
CHANGED
@@ -14,12 +14,15 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.description = "Waits so you don't have to!"
|
15
15
|
spec.homepage = 'https://github.com/meringu/waiting'
|
16
16
|
|
17
|
-
spec.files = `git ls-files -z`.split("\x0").reject
|
18
|
-
|
19
|
-
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
22
|
spec.add_development_dependency 'bundler', '~> 1.11'
|
23
|
+
spec.add_development_dependency 'guard-rspec', '~> 4.7'
|
23
24
|
spec.add_development_dependency 'rake', '~> 10.0'
|
24
25
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
|
+
spec.add_development_dependency 'simplecov', '~> 0.13.0'
|
27
|
+
spec.add_development_dependency 'yard', '~> 0.9.8'
|
25
28
|
end
|
metadata
CHANGED
@@ -1,57 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: waiting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henry Muru Paenga
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.11'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: guard-rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.7'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- - ~>
|
45
|
+
- - "~>"
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '10.0'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- - ~>
|
52
|
+
- - "~>"
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '10.0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- - ~>
|
59
|
+
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '3.0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- - ~>
|
66
|
+
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.13.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.13.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.9.8
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.9.8
|
55
97
|
description: Waits so you don't have to!
|
56
98
|
email:
|
57
99
|
- meringu@gmail.com
|
@@ -59,10 +101,12 @@ executables: []
|
|
59
101
|
extensions: []
|
60
102
|
extra_rdoc_files: []
|
61
103
|
files:
|
62
|
-
- .gitignore
|
63
|
-
- .rspec
|
64
|
-
- .
|
104
|
+
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- ".rubocop.yml"
|
107
|
+
- ".travis.yml"
|
65
108
|
- Gemfile
|
109
|
+
- Guardfile
|
66
110
|
- LICENSE
|
67
111
|
- README.md
|
68
112
|
- Rakefile
|
@@ -81,17 +125,17 @@ require_paths:
|
|
81
125
|
- lib
|
82
126
|
required_ruby_version: !ruby/object:Gem::Requirement
|
83
127
|
requirements:
|
84
|
-
- -
|
128
|
+
- - ">="
|
85
129
|
- !ruby/object:Gem::Version
|
86
130
|
version: '0'
|
87
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
132
|
requirements:
|
89
|
-
- -
|
133
|
+
- - ">="
|
90
134
|
- !ruby/object:Gem::Version
|
91
135
|
version: '0'
|
92
136
|
requirements: []
|
93
137
|
rubyforge_project:
|
94
|
-
rubygems_version: 2.4.
|
138
|
+
rubygems_version: 2.4.8
|
95
139
|
signing_key:
|
96
140
|
specification_version: 4
|
97
141
|
summary: Waits so you don't have to!
|