timers 4.1.1 → 4.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.rubocop.yml +28 -0
- data/.ruby-version +1 -0
- data/.travis.yml +13 -10
- data/CHANGES.md +31 -23
- data/Gemfile +16 -3
- data/LICENSE +1 -1
- data/README.md +27 -17
- data/Rakefile +6 -3
- data/lib/timers.rb +4 -3
- data/lib/timers/events.rb +34 -39
- data/lib/timers/group.rb +30 -35
- data/lib/timers/timer.rb +25 -24
- data/lib/timers/version.rb +3 -1
- data/lib/timers/wait.rb +17 -18
- data/spec/spec_helper.rb +5 -3
- data/spec/{cancel_spec.rb → timers/cancel_spec.rb} +12 -13
- data/spec/{events_spec.rb → timers/events_spec.rb} +20 -21
- data/spec/{every_spec.rb → timers/every_spec.rb} +1 -2
- data/spec/{group_spec.rb → timers/group_spec.rb} +19 -18
- data/spec/{performance_spec.rb → timers/performance_spec.rb} +38 -42
- data/spec/timers/strict_spec.rb +36 -0
- data/spec/{timeout_spec.rb → timers/wait_spec.rb} +11 -10
- data/timers.gemspec +16 -13
- metadata +29 -41
- data/spec/strict_spec.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97c81b8ed305099faee9ecec3ee32f6960b70d54
|
4
|
+
data.tar.gz: 90d94a796bfe60e78963b0053648396aefdb19b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbea5311bcd5fb7bfe7c98191ac15146647b91ab5c994309f3bc14fe394ac97832361afa6ff7f257d844a802265125a5bafa051026fa1eed979f8310d8a21f87
|
7
|
+
data.tar.gz: 2097c9e9d6e838550fa3c4735db828173852dd5e598670a376a04de132274df6464687cfe0e72992c2469d5d355932808fe1147e44ec5f26e2162046267c37ad
|
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
AllCops:
|
2
|
+
DisplayCopNames: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# Style
|
6
|
+
#
|
7
|
+
|
8
|
+
LineLength:
|
9
|
+
Max: 128
|
10
|
+
|
11
|
+
Style/NumericPredicate:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/SafeNavigation:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Style/StringLiterals:
|
18
|
+
EnforcedStyle: double_quotes
|
19
|
+
|
20
|
+
#
|
21
|
+
# Metrics
|
22
|
+
#
|
23
|
+
|
24
|
+
Metrics/ClassLength:
|
25
|
+
Max: 100
|
26
|
+
|
27
|
+
Metrics/MethodLength:
|
28
|
+
Max: 25
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.3
|
data/.travis.yml
CHANGED
@@ -1,18 +1,21 @@
|
|
1
|
+
language: ruby
|
2
|
+
sudo: false
|
3
|
+
|
4
|
+
bundler_args: --without development doc
|
5
|
+
|
1
6
|
rvm:
|
2
|
-
- 1.9.3
|
3
7
|
- 2.0.0
|
4
|
-
- 2.1.
|
5
|
-
-
|
6
|
-
-
|
7
|
-
- jruby-
|
8
|
-
- rbx-2
|
8
|
+
- 2.1.10
|
9
|
+
- 2.2.6
|
10
|
+
- 2.3.3
|
11
|
+
- jruby-9.1.6.0
|
9
12
|
|
10
13
|
matrix:
|
11
14
|
fast_finish: true
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
-
|
15
|
+
|
16
|
+
branches:
|
17
|
+
only:
|
18
|
+
- master
|
16
19
|
|
17
20
|
notifications:
|
18
21
|
irc: "irc.freenode.org#celluloid"
|
data/CHANGES.md
CHANGED
@@ -1,54 +1,62 @@
|
|
1
|
-
4.1.
|
2
|
-
|
1
|
+
## 4.1.2 (2016-11-26)
|
2
|
+
|
3
|
+
* RuboCop reformatting
|
4
|
+
|
5
|
+
## 4.1.1 (2015-08-21)
|
6
|
+
|
3
7
|
* Remove `RubyProf` from Gemfile and a test, due to it providing no substantial benefit while increasing problems building bundles under Rubinius.
|
4
8
|
|
5
|
-
4.1.0 (2015-08-16)
|
6
|
-
|
9
|
+
## 4.1.0 (2015-08-16)
|
10
|
+
|
7
11
|
* Addition of `now_and_every` method; fires block immediately, then sets recurring timer.
|
8
12
|
* Includes `now_and_after` method; does the same as above for one-shot timers: essentially a "two-shot" timer.
|
9
13
|
|
10
|
-
4.0.
|
11
|
-
|
14
|
+
# 4.0.4 (2015-09-01)
|
15
|
+
|
16
|
+
* Re-release of the `4.1.1` version under the `4.0.4` designation to work-around issues caused by yanking `4.0.2` a couple weeks ago.
|
17
|
+
|
18
|
+
## 4.0.1 (2014-09-10)
|
19
|
+
|
12
20
|
* Memory leak fixes
|
13
21
|
* mathn fix for those crazy enough to use it
|
14
22
|
|
15
|
-
4.0.0 (2014-07-27)
|
16
|
-
|
23
|
+
## 4.0.0 (2014-07-27)
|
24
|
+
|
17
25
|
* Replace Timers::Timeout with Timers::Wait
|
18
|
-
* Timers::Group#wait_interval now returns nil when no timers, a
|
26
|
+
* Timers::Group#wait_interval now returns nil when no timers, a positive or
|
19
27
|
negative interval which if positive is the amount of time required to wait
|
20
28
|
and if negative, how far in the past the latest timer should have fired
|
21
29
|
* Performance improvements
|
22
30
|
|
23
|
-
3.0.1 (2014-06-27)
|
24
|
-
|
31
|
+
## 3.0.1 (2014-06-27)
|
32
|
+
|
25
33
|
* Require 'set' automatically
|
26
34
|
|
27
|
-
3.0.0 (2014-06-14)
|
28
|
-
|
35
|
+
# 3.0.0 (2014-06-14)
|
36
|
+
|
29
37
|
* Refactor `Timers` class into `Timers::Group`
|
30
38
|
* Add `Timers::Timeout` class for implementing timeouts
|
31
39
|
* Fix timer fudging
|
32
40
|
* Update to RSpec 3
|
33
41
|
|
34
|
-
2.0.0 (2013-12-30)
|
35
|
-
|
42
|
+
## 2.0.0 (2013-12-30)
|
43
|
+
|
36
44
|
* Switch to Hitimes for high precision monotonic counters
|
37
45
|
* Removed Timers#time. Replaced with Timers#current_offset which provides a
|
38
46
|
monotonic time counter.
|
39
47
|
|
40
|
-
1.1.0
|
41
|
-
|
48
|
+
## 1.1.0
|
49
|
+
|
42
50
|
* Timers#after_milliseconds and #after_ms for waiting in milliseconds
|
43
51
|
|
44
|
-
1.0.2
|
45
|
-
|
52
|
+
## 1.0.2
|
53
|
+
|
46
54
|
* Handle overdue timers correctly
|
47
55
|
|
48
|
-
1.0.1
|
49
|
-
|
56
|
+
## 1.0.1
|
57
|
+
|
50
58
|
* Explicitly require Forwardable from stdlib
|
51
59
|
|
52
|
-
1.0.0
|
53
|
-
|
60
|
+
## 1.0.0
|
61
|
+
|
54
62
|
* Initial release
|
data/Gemfile
CHANGED
@@ -1,6 +1,19 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
source "https://rubygems.org"
|
4
4
|
|
5
|
-
# Specify your gem's dependencies in timers.gemspec
|
6
5
|
gemspec
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem "pry", require: false
|
9
|
+
end
|
10
|
+
|
11
|
+
group :test do
|
12
|
+
gem "rspec", "~> 3", require: false
|
13
|
+
gem "rubocop", "0.45.0", require: false
|
14
|
+
gem "coveralls", require: false
|
15
|
+
end
|
16
|
+
|
17
|
+
group :development, :test do
|
18
|
+
gem "rake"
|
19
|
+
end
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,20 +1,31 @@
|
|
1
|
-
Timers
|
2
|
-
======
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/timers.png)](http://rubygems.org/gems/timers)
|
4
|
-
[![Build Status](https://secure.travis-ci.org/celluloid/timers.png?branch=master)](http://travis-ci.org/celluloid/timers)
|
5
|
-
[![Code Climate](https://codeclimate.com/github/celluloid/timers.png)](https://codeclimate.com/github/celluloid/timers)
|
6
|
-
[![Coverage Status](https://coveralls.io/repos/celluloid/timers/badge.png?branch=master)](https://coveralls.io/r/celluloid/timers)
|
1
|
+
# Timers for Ruby [![Gem Version][gem-image]][gem-link] [![Build Status][build-image]][build-link] [![Code Climate][codeclimate-image]][codeclimate-link] [![Coverage Status][coverage-image]][coverage-link] [![MIT licensed][license-image]][license-link]
|
7
2
|
|
8
|
-
|
9
|
-
|
3
|
+
[gem-image]: https://badge.fury.io/rb/timers.svg
|
4
|
+
[gem-link]: http://rubygems.org/gems/timers
|
5
|
+
[build-image]: https://secure.travis-ci.org/celluloid/timers.svg?branch=master
|
6
|
+
[build-link]: https://travis-ci.org/celluloid/timers
|
7
|
+
[codeclimate-image]: https://codeclimate.com/github/celluloid/timers.svg
|
8
|
+
[codeclimate-link]: https://codeclimate.com/github/celluloid/timers
|
9
|
+
[coverage-image]: https://coveralls.io/repos/celluloid/timers/badge.svg?branch=master
|
10
|
+
[coverage-link]: https://coveralls.io/r/celluloid/timers
|
11
|
+
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg
|
12
|
+
[license-link]: https://github.com/celluloid/timers/master/LICENSE.txt
|
10
13
|
|
11
|
-
|
12
|
-
single timeout but you want to run multiple timers on top of it. An example of
|
13
|
-
such a library is [nio4r](https://github.com/celluloid/nio4r), a cross-platform
|
14
|
-
Ruby library for using system calls like epoll and kqueue.
|
14
|
+
Collections of one-shot and periodic timers, intended for use with event loops.
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
**Does not require Celluloid!** Though this gem was originally written
|
17
|
+
to provide the timer subsystem for [Celluloid], it can be used independently
|
18
|
+
in any sort of event loop context, or can provide a purely timer-based event
|
19
|
+
loop itself.
|
20
|
+
|
21
|
+
[Celluloid]: https://github.com/celluloid/celluloid/
|
22
|
+
|
23
|
+
## Supported platforms
|
24
|
+
|
25
|
+
* Ruby 2.0, 2.1, 2.2, and 2.3
|
26
|
+
* JRuby 9000
|
27
|
+
|
28
|
+
## Usage
|
18
29
|
|
19
30
|
Create a new timer group with `Timers::Group.new`:
|
20
31
|
|
@@ -94,10 +105,9 @@ timers.resume
|
|
94
105
|
10.times { timers.wait } # will fire all timers
|
95
106
|
```
|
96
107
|
|
97
|
-
License
|
98
|
-
-------
|
108
|
+
## License
|
99
109
|
|
100
|
-
Copyright (c)
|
110
|
+
Copyright (c) 2012-2016 Celluloid timers project developers (given in the file
|
101
111
|
AUTHORS.md).
|
102
112
|
|
103
113
|
Distributed under the MIT License. See LICENSE file for further details.
|
data/Rakefile
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require "bundler/gem_tasks"
|
3
|
-
require 'rspec/core/rake_task'
|
4
3
|
|
4
|
+
require "rspec/core/rake_task"
|
5
5
|
RSpec::Core::RakeTask.new
|
6
6
|
|
7
|
-
|
7
|
+
require "rubocop/rake_task"
|
8
|
+
RuboCop::RakeTask.new
|
9
|
+
|
10
|
+
task default: %w(spec rubocop)
|
data/lib/timers.rb
CHANGED
data/lib/timers/events.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
require
|
3
|
-
require
|
3
|
+
require "forwardable"
|
4
|
+
require "hitimes"
|
4
5
|
|
5
|
-
require
|
6
|
+
require "timers/timer"
|
6
7
|
|
7
8
|
module Timers
|
8
9
|
# Maintains an ordered list of events, which can be cancelled.
|
@@ -13,73 +14,67 @@ module Timers
|
|
13
14
|
@time = time
|
14
15
|
@callback = callback
|
15
16
|
end
|
16
|
-
|
17
|
+
|
17
18
|
# The absolute time that the handle should be fired at.
|
18
|
-
|
19
|
-
|
19
|
+
attr_reader :time
|
20
|
+
|
20
21
|
# Cancel this timer, O(1).
|
21
22
|
def cancel!
|
22
23
|
# The simplest way to keep track of cancelled status is to nullify the
|
23
24
|
# callback. This should also be optimal for garbage collection.
|
24
25
|
@callback = nil
|
25
26
|
end
|
26
|
-
|
27
|
+
|
27
28
|
# Has this timer been cancelled? Cancelled timer's don't fire.
|
28
29
|
def cancelled?
|
29
30
|
@callback.nil?
|
30
31
|
end
|
31
|
-
|
32
|
-
def >
|
32
|
+
|
33
|
+
def >(other)
|
33
34
|
@time > other.to_f
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
def to_f
|
37
38
|
@time
|
38
39
|
end
|
39
|
-
|
40
|
+
|
40
41
|
# Fire the callback if not cancelled with the given time parameter.
|
41
42
|
def fire(time)
|
42
|
-
if @callback
|
43
|
-
@callback.call(time)
|
44
|
-
end
|
43
|
+
@callback.call(time) if @callback
|
45
44
|
end
|
46
45
|
end
|
47
|
-
|
46
|
+
|
48
47
|
def initialize
|
49
48
|
# A sequence of handles, maintained in sorted order, future to present.
|
50
49
|
# @sequence.last is the next event to be fired.
|
51
50
|
@sequence = []
|
52
51
|
end
|
53
|
-
|
52
|
+
|
54
53
|
# Add an event at the given time.
|
55
54
|
def schedule(time, callback)
|
56
55
|
handle = Handle.new(time.to_f, callback)
|
57
|
-
|
56
|
+
|
58
57
|
index = bisect_left(@sequence, handle)
|
59
|
-
|
58
|
+
|
60
59
|
# Maintain sorted order, O(logN) insertion time.
|
61
60
|
@sequence.insert(index, handle)
|
62
|
-
|
63
|
-
|
61
|
+
|
62
|
+
handle
|
64
63
|
end
|
65
|
-
|
64
|
+
|
66
65
|
# Returns the first non-cancelled handle.
|
67
66
|
def first
|
68
|
-
while handle = @sequence.last
|
69
|
-
|
70
|
-
|
71
|
-
else
|
72
|
-
return handle
|
73
|
-
end
|
67
|
+
while (handle = @sequence.last)
|
68
|
+
return handle unless handle.cancelled?
|
69
|
+
@sequence.pop
|
74
70
|
end
|
75
|
-
# @sequence.reverse.find { |handle| !handle.cancelled? }
|
76
71
|
end
|
77
|
-
|
72
|
+
|
78
73
|
# Returns the number of pending (possibly cancelled) events.
|
79
74
|
def size
|
80
75
|
@sequence.size
|
81
76
|
end
|
82
|
-
|
77
|
+
|
83
78
|
# Fire all handles for which Handle#time is less than the given time.
|
84
79
|
def fire(time)
|
85
80
|
pop(time).reverse_each do |handle|
|
@@ -89,28 +84,28 @@ module Timers
|
|
89
84
|
|
90
85
|
private
|
91
86
|
|
92
|
-
# Efficiently take k handles for which Handle#time is less than the given
|
87
|
+
# Efficiently take k handles for which Handle#time is less than the given
|
93
88
|
# time.
|
94
89
|
def pop(time)
|
95
90
|
index = bisect_left(@sequence, time)
|
96
|
-
|
91
|
+
|
97
92
|
@sequence.pop(@sequence.size - index)
|
98
93
|
end
|
99
|
-
|
100
|
-
# Return the left-most index where to insert item e, in a list a, assuming
|
94
|
+
|
95
|
+
# Return the left-most index where to insert item e, in a list a, assuming
|
101
96
|
# a is sorted in descending order.
|
102
97
|
def bisect_left(a, e, l = 0, u = a.length)
|
103
98
|
while l < u
|
104
|
-
m = l + (u-l).div(2)
|
105
|
-
|
99
|
+
m = l + (u - l).div(2)
|
100
|
+
|
106
101
|
if a[m] > e
|
107
|
-
l = m+1
|
102
|
+
l = m + 1
|
108
103
|
else
|
109
104
|
u = m
|
110
105
|
end
|
111
106
|
end
|
112
|
-
|
113
|
-
|
107
|
+
|
108
|
+
l
|
114
109
|
end
|
115
110
|
end
|
116
111
|
end
|
data/lib/timers/group.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "set"
|
4
|
+
require "forwardable"
|
5
|
+
require "hitimes"
|
5
6
|
|
6
|
-
require
|
7
|
-
require
|
7
|
+
require "timers/timer"
|
8
|
+
require "timers/events"
|
8
9
|
|
9
10
|
module Timers
|
11
|
+
# A collection of timers which may fire at different times
|
10
12
|
class Group
|
11
13
|
include Enumerable
|
12
14
|
|
@@ -15,22 +17,22 @@ module Timers
|
|
15
17
|
|
16
18
|
def initialize
|
17
19
|
@events = Events.new
|
18
|
-
|
20
|
+
|
19
21
|
@timers = Set.new
|
20
22
|
@paused_timers = Set.new
|
21
|
-
|
23
|
+
|
22
24
|
@interval = Hitimes::Interval.new
|
23
25
|
@interval.start
|
24
26
|
end
|
25
27
|
|
26
28
|
# Scheduled events:
|
27
|
-
|
28
|
-
|
29
|
+
attr_reader :events
|
30
|
+
|
29
31
|
# Active timers:
|
30
|
-
|
31
|
-
|
32
|
+
attr_reader :timers
|
33
|
+
|
32
34
|
# Paused timers:
|
33
|
-
|
35
|
+
attr_reader :paused_timers
|
34
36
|
|
35
37
|
# Call the given block after the given interval. The first argument will be
|
36
38
|
# the time at which the group was asked to fire timers for.
|
@@ -41,11 +43,11 @@ module Timers
|
|
41
43
|
# Call the given block immediately, and then after the given interval. The first
|
42
44
|
# argument will be the time at which the group was asked to fire timers for.
|
43
45
|
def now_and_after(interval, &block)
|
44
|
-
|
46
|
+
yield
|
45
47
|
after(interval, &block)
|
46
48
|
end
|
47
49
|
|
48
|
-
# Call the given block periodically at the given interval. The first
|
50
|
+
# Call the given block periodically at the given interval. The first
|
49
51
|
# argument will be the time at which the group was asked to fire timers for.
|
50
52
|
def every(interval, recur = true, &block)
|
51
53
|
Timer.new(self, interval, recur, &block)
|
@@ -54,28 +56,28 @@ module Timers
|
|
54
56
|
# Call the given block immediately, and then periodically at the given interval. The first
|
55
57
|
# argument will be the time at which the group was asked to fire timers for.
|
56
58
|
def now_and_every(interval, recur = true, &block)
|
57
|
-
|
59
|
+
yield
|
58
60
|
every(interval, recur, &block)
|
59
61
|
end
|
60
62
|
|
61
63
|
# Wait for the next timer and fire it. Can take a block, which should behave
|
62
64
|
# like sleep(n), except that n may be nil (sleep forever) or a negative
|
63
65
|
# number (fire immediately after return).
|
64
|
-
def wait
|
66
|
+
def wait
|
65
67
|
if block_given?
|
66
68
|
yield wait_interval
|
67
|
-
|
68
|
-
while interval = wait_interval
|
69
|
+
|
70
|
+
while (interval = wait_interval) && interval > 0
|
69
71
|
yield interval
|
70
72
|
end
|
71
73
|
else
|
72
|
-
while interval = wait_interval
|
74
|
+
while (interval = wait_interval) && interval > 0
|
73
75
|
# We cannot assume that sleep will wait for the specified time, it might be +/- a bit.
|
74
76
|
sleep interval
|
75
77
|
end
|
76
78
|
end
|
77
79
|
|
78
|
-
|
80
|
+
fire
|
79
81
|
end
|
80
82
|
|
81
83
|
# Interval to wait until when the next timer will fire.
|
@@ -83,32 +85,27 @@ module Timers
|
|
83
85
|
# - -ve: timers expired already
|
84
86
|
# - 0: timers ready to fire
|
85
87
|
# - +ve: timers waiting to fire
|
86
|
-
def wait_interval(offset =
|
87
|
-
|
88
|
-
|
89
|
-
end
|
88
|
+
def wait_interval(offset = current_offset)
|
89
|
+
handle = @events.first
|
90
|
+
handle.time - Float(offset) if handle
|
90
91
|
end
|
91
92
|
|
92
93
|
# Fire all timers that are ready.
|
93
|
-
def fire(offset =
|
94
|
+
def fire(offset = current_offset)
|
94
95
|
@events.fire(offset)
|
95
96
|
end
|
96
97
|
|
97
98
|
# Pause all timers.
|
98
99
|
def pause
|
99
|
-
@timers.dup.each
|
100
|
-
timer.pause
|
101
|
-
end
|
100
|
+
@timers.dup.each(&:pause)
|
102
101
|
end
|
103
102
|
|
104
103
|
# Resume all timers.
|
105
104
|
def resume
|
106
|
-
@paused_timers.dup.each
|
107
|
-
timer.resume
|
108
|
-
end
|
105
|
+
@paused_timers.dup.each(&:resume)
|
109
106
|
end
|
110
107
|
|
111
|
-
|
108
|
+
alias continue resume
|
112
109
|
|
113
110
|
# Delay all timers.
|
114
111
|
def delay(seconds)
|
@@ -119,9 +116,7 @@ module Timers
|
|
119
116
|
|
120
117
|
# Cancel all timers.
|
121
118
|
def cancel
|
122
|
-
@timers.dup.each
|
123
|
-
timer.cancel
|
124
|
-
end
|
119
|
+
@timers.dup.each(&:cancel)
|
125
120
|
end
|
126
121
|
|
127
122
|
# The group's current time.
|