timers 1.1.0 → 2.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 +7 -0
- data/.coveralls.yml +1 -0
- data/.travis.yml +13 -7
- data/CHANGES.md +6 -0
- data/Gemfile +2 -0
- data/README.md +23 -2
- data/lib/timers.rb +75 -21
- data/lib/timers/version.rb +1 -1
- data/spec/spec_helper.rb +3 -1
- data/spec/timers_spec.rb +135 -11
- data/timers.gemspec +4 -1
- metadata +32 -28
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1bb812d219dd39a2f06dbead6028d0a472d43358
|
4
|
+
data.tar.gz: 069ca7cb58645d3a4bc419166d67842eb482a375
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 49534f3d20dab0cff520e02592ed0f4850230454f6fae5165990df3ad71b408b54ffe1c3e362954dc4f0fa9271f5a436f31c6bdb50b40b83d44d3aaac180c1b1
|
7
|
+
data.tar.gz: b26cf3a87ac426cc12b336ef16f3081b302da9ebd8d5e631a7ddfc5c7aed64544c4d8e1aec13dd36f1e36771506a5e077b1b0a6dca91763d2a8eb40288047dc5
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service-name: travis-pro
|
data/.travis.yml
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
rvm:
|
2
|
-
- 1.8.7
|
3
2
|
- 1.9.3
|
4
|
-
-
|
3
|
+
- 2.0.0
|
5
4
|
- ruby-head
|
6
|
-
- jruby
|
7
|
-
- jruby-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
- jruby
|
6
|
+
- jruby-head
|
7
|
+
- rbx
|
8
|
+
|
9
|
+
matrix:
|
10
|
+
allow_failures:
|
11
|
+
- rvm: ruby-head
|
12
|
+
- rvm: jruby-head
|
13
|
+
- rvm: rbx
|
14
|
+
|
15
|
+
notifications:
|
16
|
+
irc: "irc.freenode.org#celluloid"
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
2.0.0 (2013-12-30)
|
2
|
+
------------------
|
3
|
+
* Switch to Hitimes for high precision monotonic counters
|
4
|
+
* Removed Timers#time. Replaced with Timers#current_offset which provides a
|
5
|
+
monotonic time counter.
|
6
|
+
|
1
7
|
1.1.0
|
2
8
|
-----
|
3
9
|
* Timers#after_milliseconds and #after_ms for waiting in milliseconds
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
Timers
|
2
2
|
======
|
3
|
-
[](http://rubygems.org/gems/timers)
|
4
|
+
[](http://travis-ci.org/celluloid/timers)
|
5
|
+
[](https://codeclimate.com/github/celluloid/timers)
|
6
|
+
[](https://coveralls.io/r/celluloid/timers)
|
4
7
|
|
5
8
|
Pure Ruby timer collections. Schedule several procs to fire after configurable
|
6
9
|
delays or at periodic intervals.
|
7
10
|
|
8
11
|
This gem is especially useful when you are faced with an API that accepts a
|
9
12
|
single timeout but you want to run multiple timers on top of it. An example of
|
10
|
-
such a library is [nio4r](https://github.com/
|
13
|
+
such a library is [nio4r](https://github.com/celluloid/nio4r), a cross-platform
|
11
14
|
Ruby library for using system calls like epoll and kqueue.
|
12
15
|
|
13
16
|
Usage
|
@@ -66,6 +69,24 @@ loop do
|
|
66
69
|
end
|
67
70
|
```
|
68
71
|
|
72
|
+
You can also pause and continue individual timers, or all timers:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
paused_timer = timers.every(5) { puts "I was paused" }
|
76
|
+
|
77
|
+
paused_timer.pause
|
78
|
+
10.times { timers.wait } # will not fire paused timer
|
79
|
+
|
80
|
+
paused_timer.continue
|
81
|
+
10.times { timers.wait } # will fire timer
|
82
|
+
|
83
|
+
timers.pause
|
84
|
+
10.times { timers.wait } # will not fire any timers
|
85
|
+
|
86
|
+
timers.continue
|
87
|
+
10.times { timers.wait } # will fire all timers
|
88
|
+
```
|
89
|
+
|
69
90
|
License
|
70
91
|
-------
|
71
92
|
|
data/lib/timers.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'set'
|
2
2
|
require 'forwardable'
|
3
3
|
require 'timers/version'
|
4
|
+
require 'hitimes'
|
5
|
+
|
6
|
+
# Workaround for thread safety issues in SortedSet initialization
|
7
|
+
# See: https://github.com/celluloid/timers/issues/20
|
8
|
+
SortedSet.new
|
4
9
|
|
5
|
-
# Low precision timers implemented in pure Ruby
|
6
10
|
class Timers
|
7
11
|
include Enumerable
|
8
12
|
extend Forwardable
|
@@ -10,13 +14,16 @@ class Timers
|
|
10
14
|
|
11
15
|
def initialize
|
12
16
|
@timers = SortedSet.new
|
17
|
+
@paused_timers = SortedSet.new
|
18
|
+
@interval = Hitimes::Interval.new
|
19
|
+
@interval.start
|
13
20
|
end
|
14
21
|
|
15
22
|
# Call the given block after the given interval
|
16
23
|
def after(interval, &block)
|
17
24
|
Timer.new(self, interval, false, &block)
|
18
25
|
end
|
19
|
-
|
26
|
+
|
20
27
|
# Call the given block after the given interval has expired. +interval+
|
21
28
|
# is measured in milliseconds.
|
22
29
|
#
|
@@ -40,19 +47,19 @@ class Timers
|
|
40
47
|
end
|
41
48
|
|
42
49
|
# Interval to wait until when the next timer will fire
|
43
|
-
def wait_interval(
|
50
|
+
def wait_interval(offset = self.current_offset)
|
44
51
|
timer = @timers.first
|
45
52
|
return unless timer
|
46
|
-
interval = timer.
|
53
|
+
interval = timer.offset - Float(offset)
|
47
54
|
interval > 0 ? interval : 0
|
48
55
|
end
|
49
56
|
|
50
57
|
# Fire all timers that are ready
|
51
|
-
def fire(
|
52
|
-
time =
|
53
|
-
while (timer = @timers.first) && (time >= timer.
|
58
|
+
def fire(offset = self.current_offset)
|
59
|
+
time = Float(offset) + 0.001 # Fudge 1ms in case of clock imprecision
|
60
|
+
while (timer = @timers.first) && (time >= timer.offset)
|
54
61
|
@timers.delete timer
|
55
|
-
timer.fire(
|
62
|
+
timer.fire(offset)
|
56
63
|
end
|
57
64
|
end
|
58
65
|
|
@@ -61,23 +68,53 @@ class Timers
|
|
61
68
|
@timers.add(timer)
|
62
69
|
end
|
63
70
|
|
71
|
+
def pause(timer = nil)
|
72
|
+
return pause_all if timer.nil?
|
73
|
+
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
74
|
+
@timers.delete timer
|
75
|
+
@paused_timers.add timer
|
76
|
+
end
|
77
|
+
|
78
|
+
def pause_all
|
79
|
+
@timers.each {|timer| timer.pause}
|
80
|
+
end
|
81
|
+
|
82
|
+
def continue(timer = nil)
|
83
|
+
return continue_all if timer.nil?
|
84
|
+
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
85
|
+
@paused_timers.delete timer
|
86
|
+
@timers.add timer
|
87
|
+
end
|
88
|
+
|
89
|
+
def continue_all
|
90
|
+
@paused_timers.each {|timer| timer.continue}
|
91
|
+
end
|
92
|
+
|
93
|
+
def delay(seconds)
|
94
|
+
@timers.each {|timer| timer.delay(seconds)}
|
95
|
+
end
|
96
|
+
|
64
97
|
alias_method :cancel, :delete
|
65
98
|
|
99
|
+
def current_offset
|
100
|
+
@interval.to_f
|
101
|
+
end
|
102
|
+
|
66
103
|
# An individual timer set to fire a given proc at a given time
|
67
104
|
class Timer
|
68
105
|
include Comparable
|
69
|
-
attr_reader :interval, :
|
106
|
+
attr_reader :interval, :offset, :recurring
|
70
107
|
|
71
108
|
def initialize(timers, interval, recurring = false, &block)
|
72
109
|
@timers, @interval, @recurring = timers, interval, recurring
|
73
|
-
@block
|
74
|
-
@
|
110
|
+
@block = block
|
111
|
+
@offset = nil
|
75
112
|
|
76
113
|
reset
|
77
114
|
end
|
78
115
|
|
79
116
|
def <=>(other)
|
80
|
-
@
|
117
|
+
@offset <=> other.offset
|
81
118
|
end
|
82
119
|
|
83
120
|
# Cancel this timer
|
@@ -85,30 +122,47 @@ class Timers
|
|
85
122
|
@timers.cancel self
|
86
123
|
end
|
87
124
|
|
125
|
+
# Extend this timer
|
126
|
+
def delay(seconds)
|
127
|
+
@timers.delete self
|
128
|
+
@offset += seconds
|
129
|
+
@timers.add self
|
130
|
+
end
|
131
|
+
|
88
132
|
# Reset this timer
|
89
|
-
def reset(
|
133
|
+
def reset(offset = @timers.current_offset)
|
90
134
|
@timers.cancel self if @time
|
91
|
-
@
|
135
|
+
@offset = Float(offset) + @interval
|
92
136
|
@timers.add self
|
93
137
|
end
|
94
138
|
|
95
139
|
# Fire the block
|
96
|
-
def fire(
|
97
|
-
reset(
|
140
|
+
def fire(offset = @timers.current_offset)
|
141
|
+
reset(offset) if recurring
|
98
142
|
@block.call
|
99
143
|
end
|
100
144
|
alias_method :call, :fire
|
101
145
|
|
146
|
+
# Pause this timer
|
147
|
+
def pause
|
148
|
+
@timers.pause self
|
149
|
+
end
|
150
|
+
|
151
|
+
# Continue this timer
|
152
|
+
def continue
|
153
|
+
@timers.continue self
|
154
|
+
end
|
155
|
+
|
102
156
|
# Inspect a timer
|
103
157
|
def inspect
|
104
158
|
str = "#<Timers::Timer:#{object_id.to_s(16)} "
|
105
|
-
|
159
|
+
offset = @timers.current_offset
|
106
160
|
|
107
|
-
if @
|
108
|
-
if @
|
109
|
-
str << "fires in #{@
|
161
|
+
if @offset
|
162
|
+
if @offset >= offset
|
163
|
+
str << "fires in #{@offset - offset} seconds"
|
110
164
|
else
|
111
|
-
str << "fired #{
|
165
|
+
str << "fired #{offset - @offset} seconds ago"
|
112
166
|
end
|
113
167
|
|
114
168
|
str << ", recurs every #{interval}" if recurring
|
data/lib/timers/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/timers_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Timers do
|
4
|
-
# Level of accuracy enforced by
|
4
|
+
# Level of accuracy enforced by tests (50ms)
|
5
5
|
Q = 0.05
|
6
6
|
|
7
7
|
it "sleeps until the next timer" do
|
@@ -12,8 +12,8 @@ describe Timers do
|
|
12
12
|
subject.after(interval) { fired = true }
|
13
13
|
subject.wait
|
14
14
|
|
15
|
-
fired.
|
16
|
-
(Time.now - started_at).
|
15
|
+
expect(fired).to be_true
|
16
|
+
expect(Time.now - started_at).to be_within(Q).of interval
|
17
17
|
end
|
18
18
|
|
19
19
|
it "fires instantly when next timer is in the past" do
|
@@ -22,17 +22,17 @@ describe Timers do
|
|
22
22
|
sleep(Q * 2)
|
23
23
|
subject.wait
|
24
24
|
|
25
|
-
fired.
|
25
|
+
expect(fired).to be_true
|
26
26
|
end
|
27
27
|
|
28
28
|
it "calculates the interval until the next timer should fire" do
|
29
29
|
interval = 0.1
|
30
30
|
|
31
31
|
subject.after(interval)
|
32
|
-
subject.wait_interval.
|
32
|
+
expect(subject.wait_interval).to be_within(Q).of interval
|
33
33
|
|
34
34
|
sleep(interval)
|
35
|
-
subject.wait_interval.
|
35
|
+
expect(subject.wait_interval).to be(0)
|
36
36
|
end
|
37
37
|
|
38
38
|
it "fires timers in the correct order" do
|
@@ -45,7 +45,13 @@ describe Timers do
|
|
45
45
|
sleep Q * 4
|
46
46
|
subject.fire
|
47
47
|
|
48
|
-
result.
|
48
|
+
expect(result).to eq [:one, :two, :three]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "raises TypeError if given an invalid time" do
|
52
|
+
expect do
|
53
|
+
subject.after(nil) { nil }
|
54
|
+
end.to raise_exception(TypeError)
|
49
55
|
end
|
50
56
|
|
51
57
|
describe "recurring timers" do
|
@@ -56,14 +62,14 @@ describe Timers do
|
|
56
62
|
|
57
63
|
sleep Q * 3
|
58
64
|
subject.fire
|
59
|
-
result.
|
65
|
+
expect(result).to eq [:foo]
|
60
66
|
|
61
67
|
sleep Q * 5
|
62
68
|
subject.fire
|
63
|
-
result.
|
69
|
+
expect(result).to eq [:foo, :foo]
|
64
70
|
end
|
65
71
|
end
|
66
|
-
|
72
|
+
|
67
73
|
describe "millisecond timers" do
|
68
74
|
it "calculates the proper interval to wait until firing" do
|
69
75
|
interval_ms = 25
|
@@ -71,7 +77,125 @@ describe Timers do
|
|
71
77
|
subject.after_milliseconds(interval_ms)
|
72
78
|
expected_elapse = subject.wait_interval
|
73
79
|
|
74
|
-
subject.wait_interval.
|
80
|
+
expect(subject.wait_interval).to be_within(Q).of(interval_ms / 1000.0)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "pause and continue timers" do
|
85
|
+
before(:each) do
|
86
|
+
@interval = Q * 2
|
87
|
+
started_at = Time.now
|
88
|
+
|
89
|
+
@fired = false
|
90
|
+
@timer = subject.every(@interval) { @fired = true }
|
91
|
+
@fired2 = false
|
92
|
+
@timer2 = subject.every(@interval) { @fired2 = true }
|
93
|
+
end
|
94
|
+
|
95
|
+
it "does not fire when paused" do
|
96
|
+
@timer.pause
|
97
|
+
subject.wait
|
98
|
+
expect(@fired).to be_false
|
99
|
+
end
|
100
|
+
|
101
|
+
it "fires when continued after pause" do
|
102
|
+
@timer.pause
|
103
|
+
subject.wait
|
104
|
+
@timer.continue
|
105
|
+
subject.wait
|
106
|
+
expect(@fired).to be_true
|
107
|
+
end
|
108
|
+
|
109
|
+
it "can pause all timers at once" do
|
110
|
+
subject.pause
|
111
|
+
subject.wait
|
112
|
+
expect(@fired).to be_false
|
113
|
+
expect(@fired2).to be_false
|
114
|
+
end
|
115
|
+
|
116
|
+
it "can continue all timers at once" do
|
117
|
+
subject.pause
|
118
|
+
subject.wait
|
119
|
+
subject.continue
|
120
|
+
subject.wait
|
121
|
+
expect(@fired).to be_true
|
122
|
+
expect(@fired2).to be_true
|
123
|
+
end
|
124
|
+
|
125
|
+
it "can fire the timer directly" do
|
126
|
+
fired = false
|
127
|
+
timer = subject.after( Q * 1 ) { fired = true }
|
128
|
+
timer.pause
|
129
|
+
subject.wait
|
130
|
+
expect(fired).not_to be_true
|
131
|
+
timer.continue
|
132
|
+
expect(fired).not_to be_true
|
133
|
+
timer.fire
|
134
|
+
expect(fired).to be_true
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "delay timer" do
|
140
|
+
it "adds appropriate amount of time to timer" do
|
141
|
+
timer = subject.after(10)
|
142
|
+
timer.delay(5)
|
143
|
+
expect(timer.offset - subject.current_offset).to be_within(Q).of(15)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "delay timer collection" do
|
148
|
+
it "delay on set adds appropriate amount of time to all timers" do
|
149
|
+
timer = subject.after(10)
|
150
|
+
timer2 = subject.after(20)
|
151
|
+
subject.delay(5)
|
152
|
+
expect(timer.offset - subject.current_offset).to be_within(Q).of(15)
|
153
|
+
expect(timer2.offset - subject.current_offset).to be_within(Q).of(25)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "on delaying a timer" do
|
158
|
+
it "fires timers in the correct order" do
|
159
|
+
result = []
|
160
|
+
|
161
|
+
second = subject.after(Q * 2) { result << :two }
|
162
|
+
third = subject.after(Q * 3) { result << :three }
|
163
|
+
first = subject.after(Q * 1) { result << :one }
|
164
|
+
first.delay(Q * 3)
|
165
|
+
|
166
|
+
sleep Q * 5
|
167
|
+
subject.fire
|
168
|
+
|
169
|
+
expect(result).to eq [:two, :three, :one]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "Timer inspection" do
|
174
|
+
it "before firing" do
|
175
|
+
fired = false
|
176
|
+
timer = subject.after(Q * 5) { fired = true }
|
177
|
+
timer.pause
|
178
|
+
expect(fired).not_to be_true
|
179
|
+
expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fires in [-\.\de]+ seconds>\Z/)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "after firing" do
|
183
|
+
fired = false
|
184
|
+
timer = subject.after(Q) { fired = true }
|
185
|
+
|
186
|
+
subject.wait
|
187
|
+
|
188
|
+
expect(fired).to be_true
|
189
|
+
expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fired [-\.\de]+ seconds ago>\Z/)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "recurring firing" do
|
193
|
+
result = []
|
194
|
+
timer = subject.every(Q) { result << :foo }
|
195
|
+
|
196
|
+
subject.wait
|
197
|
+
expect(result).not_to be_empty
|
198
|
+
expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fires in [-\.\de]+ seconds, recurs every #{sprintf("%0.2f", Q)}>\Z/)
|
75
199
|
end
|
76
200
|
end
|
77
201
|
end
|
data/timers.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.email = ["tony.arcieri@gmail.com"]
|
7
7
|
gem.description = "Pure Ruby one-shot and periodic timers"
|
8
8
|
gem.summary = "Schedule procs to run after a certain time, or at periodic intervals, using any API that accepts a timeout"
|
9
|
-
gem.homepage = "https://github.com/
|
9
|
+
gem.homepage = "https://github.com/celluloid/timers"
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
12
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -14,6 +14,9 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.name = "timers"
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Timers::VERSION
|
17
|
+
gem.licenses = ['MIT']
|
18
|
+
|
19
|
+
gem.add_runtime_dependency 'hitimes'
|
17
20
|
|
18
21
|
gem.add_development_dependency 'rake'
|
19
22
|
gem.add_development_dependency 'rspec'
|
metadata
CHANGED
@@ -1,46 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 2.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Tony Arcieri
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-12-30 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hitimes
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
14
27
|
- !ruby/object:Gem::Dependency
|
15
28
|
name: rake
|
16
29
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
30
|
requirements:
|
19
|
-
- -
|
31
|
+
- - ">="
|
20
32
|
- !ruby/object:Gem::Version
|
21
33
|
version: '0'
|
22
34
|
type: :development
|
23
35
|
prerelease: false
|
24
36
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
37
|
requirements:
|
27
|
-
- -
|
38
|
+
- - ">="
|
28
39
|
- !ruby/object:Gem::Version
|
29
40
|
version: '0'
|
30
41
|
- !ruby/object:Gem::Dependency
|
31
42
|
name: rspec
|
32
43
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
44
|
requirements:
|
35
|
-
- -
|
45
|
+
- - ">="
|
36
46
|
- !ruby/object:Gem::Version
|
37
47
|
version: '0'
|
38
48
|
type: :development
|
39
49
|
prerelease: false
|
40
50
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
51
|
requirements:
|
43
|
-
- -
|
52
|
+
- - ">="
|
44
53
|
- !ruby/object:Gem::Version
|
45
54
|
version: '0'
|
46
55
|
description: Pure Ruby one-shot and periodic timers
|
@@ -50,9 +59,10 @@ executables: []
|
|
50
59
|
extensions: []
|
51
60
|
extra_rdoc_files: []
|
52
61
|
files:
|
53
|
-
- .
|
54
|
-
- .
|
55
|
-
- .
|
62
|
+
- ".coveralls.yml"
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".travis.yml"
|
56
66
|
- CHANGES.md
|
57
67
|
- Gemfile
|
58
68
|
- LICENSE
|
@@ -63,35 +73,29 @@ files:
|
|
63
73
|
- spec/spec_helper.rb
|
64
74
|
- spec/timers_spec.rb
|
65
75
|
- timers.gemspec
|
66
|
-
homepage: https://github.com/
|
67
|
-
licenses:
|
76
|
+
homepage: https://github.com/celluloid/timers
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
68
80
|
post_install_message:
|
69
81
|
rdoc_options: []
|
70
82
|
require_paths:
|
71
83
|
- lib
|
72
84
|
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
85
|
requirements:
|
75
|
-
- -
|
86
|
+
- - ">="
|
76
87
|
- !ruby/object:Gem::Version
|
77
88
|
version: '0'
|
78
|
-
segments:
|
79
|
-
- 0
|
80
|
-
hash: 1264960547307952819
|
81
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
90
|
requirements:
|
84
|
-
- -
|
91
|
+
- - ">="
|
85
92
|
- !ruby/object:Gem::Version
|
86
93
|
version: '0'
|
87
|
-
segments:
|
88
|
-
- 0
|
89
|
-
hash: 1264960547307952819
|
90
94
|
requirements: []
|
91
95
|
rubyforge_project:
|
92
|
-
rubygems_version:
|
96
|
+
rubygems_version: 2.2.0
|
93
97
|
signing_key:
|
94
|
-
specification_version:
|
98
|
+
specification_version: 4
|
95
99
|
summary: Schedule procs to run after a certain time, or at periodic intervals, using
|
96
100
|
any API that accepts a timeout
|
97
101
|
test_files:
|