timers 4.3.0 → 4.3.2
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 +4 -4
- data/lib/timers.rb +23 -8
- data/lib/timers/events.rb +20 -5
- data/lib/timers/group.rb +20 -5
- data/lib/timers/interval.rb +20 -5
- data/lib/timers/timer.rb +20 -5
- data/lib/timers/version.rb +21 -6
- data/lib/timers/wait.rb +20 -5
- metadata +20 -47
- data/.editorconfig +0 -6
- data/.gitignore +0 -17
- data/.rspec +0 -3
- data/.travis.yml +0 -20
- data/Gemfile +0 -15
- data/README.md +0 -149
- data/Rakefile +0 -6
- data/spec/spec_helper.rb +0 -40
- data/spec/timers/cancel_spec.rb +0 -50
- data/spec/timers/events_spec.rb +0 -61
- data/spec/timers/every_spec.rb +0 -38
- data/spec/timers/group_spec.rb +0 -260
- data/spec/timers/performance_spec.rb +0 -124
- data/spec/timers/strict_spec.rb +0 -39
- data/spec/timers/wait_spec.rb +0 -35
- data/timers.gemspec +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52ef1e26aab6a7bbbf5c9d687028bdc36f52810dd7ebc0c76873b6bef9f30ca2
|
4
|
+
data.tar.gz: 26105fe04a6d2bfcdf9efb46ebd83d9562a08af3c2f113892a8be57713be6112
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a3ae0e0d9644627fef3aeffdfde86456d74c28ab89194486743fee2a25e8832c5aafb05f88174f6ee27d4f9402e05b4f80776c49cc34d70da527e63f9097685
|
7
|
+
data.tar.gz: 1f30b97aa11f6f42b3ce1786ae42f06334a86064306601635774b8d84cc88df765e8312a455798984520d44e3db35f8094fb23ec35cb736eb2191bfa27dece0c
|
data/lib/timers.rb
CHANGED
@@ -1,11 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
2
|
|
8
|
-
|
3
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
9
22
|
|
10
|
-
|
11
|
-
|
23
|
+
require_relative "timers/version"
|
24
|
+
|
25
|
+
require_relative "timers/group"
|
26
|
+
require_relative "timers/wait"
|
data/lib/timers/events.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
2
|
+
|
3
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
7
22
|
|
8
23
|
require_relative "timer"
|
9
24
|
|
data/lib/timers/group.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
2
|
+
|
3
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
7
22
|
|
8
23
|
require "set"
|
9
24
|
require "forwardable"
|
data/lib/timers/interval.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
2
|
+
|
3
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
7
22
|
|
8
23
|
module Timers
|
9
24
|
# A collection of timers which may fire at different times
|
data/lib/timers/timer.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
2
|
+
|
3
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
7
22
|
|
8
23
|
module Timers
|
9
24
|
# An individual timer set to fire a given proc at a given time. A timer is
|
data/lib/timers/version.rb
CHANGED
@@ -1,10 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
2
|
+
|
3
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
7
22
|
|
8
23
|
module Timers
|
9
|
-
VERSION = "4.3.
|
24
|
+
VERSION = "4.3.2"
|
10
25
|
end
|
data/lib/timers/wait.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
2
|
+
|
3
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
7
22
|
|
8
23
|
require_relative "interval"
|
9
24
|
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.3.
|
4
|
+
version: 4.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
- Tony Arcieri
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-09-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -26,49 +26,39 @@ dependencies:
|
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
29
|
+
name: covered
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - "
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
34
|
+
version: '0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - "
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
41
|
+
version: '0'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
43
|
+
name: rspec
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '0'
|
48
|
+
version: '3.0'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - "
|
53
|
+
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '0'
|
56
|
-
description:
|
57
|
-
using any API that accepts a timeout.
|
55
|
+
version: '3.0'
|
56
|
+
description:
|
58
57
|
email:
|
59
|
-
- samuel@codeotaku.com
|
60
|
-
- bascule@gmail.com
|
61
58
|
executables: []
|
62
59
|
extensions: []
|
63
60
|
extra_rdoc_files: []
|
64
61
|
files:
|
65
|
-
- ".editorconfig"
|
66
|
-
- ".gitignore"
|
67
|
-
- ".rspec"
|
68
|
-
- ".travis.yml"
|
69
|
-
- Gemfile
|
70
|
-
- README.md
|
71
|
-
- Rakefile
|
72
62
|
- lib/timers.rb
|
73
63
|
- lib/timers/events.rb
|
74
64
|
- lib/timers/group.rb
|
@@ -76,20 +66,11 @@ files:
|
|
76
66
|
- lib/timers/timer.rb
|
77
67
|
- lib/timers/version.rb
|
78
68
|
- lib/timers/wait.rb
|
79
|
-
- spec/spec_helper.rb
|
80
|
-
- spec/timers/cancel_spec.rb
|
81
|
-
- spec/timers/events_spec.rb
|
82
|
-
- spec/timers/every_spec.rb
|
83
|
-
- spec/timers/group_spec.rb
|
84
|
-
- spec/timers/performance_spec.rb
|
85
|
-
- spec/timers/strict_spec.rb
|
86
|
-
- spec/timers/wait_spec.rb
|
87
|
-
- timers.gemspec
|
88
69
|
homepage: https://github.com/socketry/timers
|
89
70
|
licenses:
|
90
71
|
- MIT
|
91
72
|
metadata: {}
|
92
|
-
post_install_message:
|
73
|
+
post_install_message:
|
93
74
|
rdoc_options: []
|
94
75
|
require_paths:
|
95
76
|
- lib
|
@@ -97,23 +78,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
78
|
requirements:
|
98
79
|
- - ">="
|
99
80
|
- !ruby/object:Gem::Version
|
100
|
-
version:
|
81
|
+
version: '0'
|
101
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
83
|
requirements:
|
103
84
|
- - ">="
|
104
85
|
- !ruby/object:Gem::Version
|
105
86
|
version: '0'
|
106
87
|
requirements: []
|
107
|
-
rubygems_version: 3.
|
108
|
-
signing_key:
|
88
|
+
rubygems_version: 3.1.2
|
89
|
+
signing_key:
|
109
90
|
specification_version: 4
|
110
|
-
summary: Pure Ruby one-shot and periodic timers
|
111
|
-
test_files:
|
112
|
-
- spec/spec_helper.rb
|
113
|
-
- spec/timers/cancel_spec.rb
|
114
|
-
- spec/timers/events_spec.rb
|
115
|
-
- spec/timers/every_spec.rb
|
116
|
-
- spec/timers/group_spec.rb
|
117
|
-
- spec/timers/performance_spec.rb
|
118
|
-
- spec/timers/strict_spec.rb
|
119
|
-
- spec/timers/wait_spec.rb
|
91
|
+
summary: Pure Ruby one-shot and periodic timers.
|
92
|
+
test_files: []
|
data/.editorconfig
DELETED
data/.gitignore
DELETED
data/.rspec
DELETED
data/.travis.yml
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
dist: xenial
|
3
|
-
cache: bundler
|
4
|
-
|
5
|
-
matrix:
|
6
|
-
include:
|
7
|
-
- rvm: 2.3
|
8
|
-
- rvm: 2.4
|
9
|
-
- rvm: 2.5
|
10
|
-
- rvm: 2.6
|
11
|
-
- rvm: jruby-head
|
12
|
-
env: JRUBY_OPTS="--debug -X+O"
|
13
|
-
- rvm: truffleruby
|
14
|
-
- rvm: ruby-head
|
15
|
-
- rvm: rbx-3
|
16
|
-
allow_failures:
|
17
|
-
- rvm: ruby-head
|
18
|
-
- rvm: jruby-head
|
19
|
-
- rvm: rbx-3
|
20
|
-
- rvm: truffleruby
|
data/Gemfile
DELETED
data/README.md
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
# Timers
|
2
|
-
|
3
|
-
Collections of one-shot and periodic timers, intended for use with event loops such as [async].
|
4
|
-
|
5
|
-
[](https://travis-ci.org/socketry/timers)
|
6
|
-
[](https://codeclimate.com/github/socketry/timers)
|
7
|
-
[](https://coveralls.io/r/socketry/timers)
|
8
|
-
|
9
|
-
[async]: https://github.com/socketry/async
|
10
|
-
|
11
|
-
## Installation
|
12
|
-
|
13
|
-
Add this line to your application's Gemfile:
|
14
|
-
|
15
|
-
```ruby
|
16
|
-
gem 'timers'
|
17
|
-
```
|
18
|
-
|
19
|
-
And then execute:
|
20
|
-
|
21
|
-
$ bundle
|
22
|
-
|
23
|
-
Or install it yourself as:
|
24
|
-
|
25
|
-
$ gem install timers
|
26
|
-
|
27
|
-
## Usage
|
28
|
-
|
29
|
-
Create a new timer group with `Timers::Group.new`:
|
30
|
-
|
31
|
-
```ruby
|
32
|
-
require 'timers'
|
33
|
-
|
34
|
-
timers = Timers::Group.new
|
35
|
-
```
|
36
|
-
|
37
|
-
Schedule a proc to run after 5 seconds with `Timers::Group#after`:
|
38
|
-
|
39
|
-
```ruby
|
40
|
-
five_second_timer = timers.after(5) { puts "Take five" }
|
41
|
-
```
|
42
|
-
|
43
|
-
The `five_second_timer` variable is now bound to a Timers::Timer object. To
|
44
|
-
cancel a timer, use `Timers::Timer#cancel`
|
45
|
-
|
46
|
-
Once you've scheduled a timer, you can wait until the next timer fires with `Timers::Group#wait`:
|
47
|
-
|
48
|
-
```ruby
|
49
|
-
# Waits 5 seconds
|
50
|
-
timers.wait
|
51
|
-
|
52
|
-
# The script will now print "Take five"
|
53
|
-
```
|
54
|
-
|
55
|
-
You can schedule a block to run periodically with `Timers::Group#every`:
|
56
|
-
|
57
|
-
```ruby
|
58
|
-
every_five_seconds = timers.every(5) { puts "Another 5 seconds" }
|
59
|
-
|
60
|
-
loop { timers.wait }
|
61
|
-
```
|
62
|
-
|
63
|
-
You can also schedule a block to run immediately and periodically with `Timers::Group#now_and_every`:
|
64
|
-
```ruby
|
65
|
-
now_and_every_five_seconds = timers.now_and_every(5) { puts "Now and in another 5 seconds" }
|
66
|
-
|
67
|
-
loop { timers.wait }
|
68
|
-
```
|
69
|
-
|
70
|
-
If you'd like another method to do the waiting for you, e.g. `Kernel.select`,
|
71
|
-
you can use `Timers::Group#wait_interval` to obtain the amount of time to wait. When
|
72
|
-
a timeout is encountered, you can fire all pending timers with `Timers::Group#fire`:
|
73
|
-
|
74
|
-
```ruby
|
75
|
-
loop do
|
76
|
-
interval = timers.wait_interval
|
77
|
-
ready_readers, ready_writers = select readers, writers, nil, interval
|
78
|
-
|
79
|
-
if ready_readers || ready_writers
|
80
|
-
# Handle IO
|
81
|
-
...
|
82
|
-
else
|
83
|
-
# Timeout!
|
84
|
-
timers.fire
|
85
|
-
end
|
86
|
-
end
|
87
|
-
```
|
88
|
-
|
89
|
-
You can also pause and continue individual timers, or all timers:
|
90
|
-
|
91
|
-
```ruby
|
92
|
-
paused_timer = timers.every(5) { puts "I was paused" }
|
93
|
-
|
94
|
-
paused_timer.pause
|
95
|
-
10.times { timers.wait } # will not fire paused timer
|
96
|
-
|
97
|
-
paused_timer.resume
|
98
|
-
10.times { timers.wait } # will fire timer
|
99
|
-
|
100
|
-
timers.pause
|
101
|
-
10.times { timers.wait } # will not fire any timers
|
102
|
-
|
103
|
-
timers.resume
|
104
|
-
10.times { timers.wait } # will fire all timers
|
105
|
-
```
|
106
|
-
|
107
|
-
## Contributing
|
108
|
-
|
109
|
-
1. Fork it
|
110
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
111
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
112
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
113
|
-
5. Create new Pull Request
|
114
|
-
|
115
|
-
## License
|
116
|
-
|
117
|
-
Released under the MIT license.
|
118
|
-
|
119
|
-
Copyright, 2018, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
|
120
|
-
Copyright, 2016, by [Tony Arcieri](bascule@gmail.com).
|
121
|
-
Copyright, 2016, by Jeremy Hinegardner.
|
122
|
-
Copyright, 2016, by Sean Gregory.
|
123
|
-
Copyright, 2016, by Chuck Remes.
|
124
|
-
Copyright, 2016, by Utenmiki.
|
125
|
-
Copyright, 2016, by Ron Evans.
|
126
|
-
Copyright, 2016, by Larry Lv.
|
127
|
-
Copyright, 2016, by Bruno Enten.
|
128
|
-
Copyright, 2016, by Jesse Cooke.
|
129
|
-
Copyright, 2016, by Nicholas Evans.
|
130
|
-
Copyright, 2016, by Dimitrij Denissenko.
|
131
|
-
Copyright, 2016, by Ryan LeCompte.
|
132
|
-
|
133
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
134
|
-
of this software and associated documentation files (the "Software"), to deal
|
135
|
-
in the Software without restriction, including without limitation the rights
|
136
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
137
|
-
copies of the Software, and to permit persons to whom the Software is
|
138
|
-
furnished to do so, subject to the following conditions:
|
139
|
-
|
140
|
-
The above copyright notice and this permission notice shall be included in
|
141
|
-
all copies or substantial portions of the Software.
|
142
|
-
|
143
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
144
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
145
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
146
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
147
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
148
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
149
|
-
THE SOFTWARE.
|
data/Rakefile
DELETED
data/spec/spec_helper.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
|
-
|
8
|
-
# Level of accuracy enforced by tests (50ms)
|
9
|
-
TIMER_QUANTUM = 0.05
|
10
|
-
|
11
|
-
if ENV['COVERAGE'] || ENV['TRAVIS']
|
12
|
-
begin
|
13
|
-
require 'simplecov'
|
14
|
-
|
15
|
-
SimpleCov.start do
|
16
|
-
add_filter "/spec/"
|
17
|
-
end
|
18
|
-
|
19
|
-
if ENV['TRAVIS']
|
20
|
-
require 'coveralls'
|
21
|
-
Coveralls.wear!
|
22
|
-
end
|
23
|
-
rescue LoadError
|
24
|
-
warn "Could not load simplecov: #{$!}"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
require 'bundler/setup'
|
29
|
-
Bundler.require(:test)
|
30
|
-
|
31
|
-
require 'timers'
|
32
|
-
|
33
|
-
RSpec.configure do |config|
|
34
|
-
# Enable flags like --only-failures and --next-failure
|
35
|
-
config.example_status_persistence_file_path = ".rspec_status"
|
36
|
-
|
37
|
-
config.expect_with :rspec do |c|
|
38
|
-
c.syntax = :expect
|
39
|
-
end
|
40
|
-
end
|
data/spec/timers/cancel_spec.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
|
-
|
8
|
-
RSpec.describe Timers::Group do
|
9
|
-
it "should be able to cancel twice" do
|
10
|
-
fired = false
|
11
|
-
|
12
|
-
timer = subject.after(0.1) { fired = true }
|
13
|
-
|
14
|
-
2.times do
|
15
|
-
timer.cancel
|
16
|
-
subject.wait
|
17
|
-
end
|
18
|
-
|
19
|
-
expect(fired).to be false
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should be possble to reset after cancel" do
|
23
|
-
fired = false
|
24
|
-
|
25
|
-
timer = subject.after(0.1) { fired = true }
|
26
|
-
timer.cancel
|
27
|
-
|
28
|
-
subject.wait
|
29
|
-
|
30
|
-
timer.reset
|
31
|
-
|
32
|
-
subject.wait
|
33
|
-
|
34
|
-
expect(fired).to be true
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should cancel and remove one shot timers after they fire" do
|
38
|
-
x = 0
|
39
|
-
|
40
|
-
Timers::Wait.for(2) do |_remaining|
|
41
|
-
timer = subject.every(0.2) { x += 1 }
|
42
|
-
subject.after(0.1) { timer.cancel }
|
43
|
-
|
44
|
-
subject.wait
|
45
|
-
end
|
46
|
-
|
47
|
-
expect(subject.timers).to be_empty
|
48
|
-
expect(x).to be == 0
|
49
|
-
end
|
50
|
-
end
|
data/spec/timers/events_spec.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
|
-
|
8
|
-
RSpec.describe Timers::Events do
|
9
|
-
it "should register an event" do
|
10
|
-
fired = false
|
11
|
-
|
12
|
-
callback = proc do |_time|
|
13
|
-
fired = true
|
14
|
-
end
|
15
|
-
|
16
|
-
subject.schedule(0.1, callback)
|
17
|
-
|
18
|
-
expect(subject.size).to be == 1
|
19
|
-
|
20
|
-
subject.fire(0.15)
|
21
|
-
|
22
|
-
expect(subject.size).to be == 0
|
23
|
-
|
24
|
-
expect(fired).to be true
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should register events in order" do
|
28
|
-
fired = []
|
29
|
-
|
30
|
-
times = [0.95, 0.1, 0.3, 0.5, 0.4, 0.2, 0.01, 0.9]
|
31
|
-
|
32
|
-
times.each do |requested_time|
|
33
|
-
callback = proc do |_time|
|
34
|
-
fired << requested_time
|
35
|
-
end
|
36
|
-
|
37
|
-
subject.schedule(requested_time, callback)
|
38
|
-
end
|
39
|
-
|
40
|
-
subject.fire(0.5)
|
41
|
-
expect(fired).to be == times.sort.first(6)
|
42
|
-
|
43
|
-
subject.fire(1.0)
|
44
|
-
expect(fired).to be == times.sort
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should fire events with the time they were fired at" do
|
48
|
-
fired_at = :not_fired
|
49
|
-
|
50
|
-
callback = proc do |time|
|
51
|
-
# The time we actually were fired at:
|
52
|
-
fired_at = time
|
53
|
-
end
|
54
|
-
|
55
|
-
subject.schedule(0.5, callback)
|
56
|
-
|
57
|
-
subject.fire(1.0)
|
58
|
-
|
59
|
-
expect(fired_at).to be == 1.0
|
60
|
-
end
|
61
|
-
end
|
data/spec/timers/every_spec.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
|
-
|
8
|
-
RSpec.describe Timers::Group do
|
9
|
-
it "should fire several times" do
|
10
|
-
result = []
|
11
|
-
|
12
|
-
subject.every(0.7) { result << :a }
|
13
|
-
subject.every(2.3) { result << :b }
|
14
|
-
subject.every(1.3) { result << :c }
|
15
|
-
subject.every(2.4) { result << :d }
|
16
|
-
|
17
|
-
Timers::Wait.for(2.5) do |remaining|
|
18
|
-
subject.wait if subject.wait_interval < remaining
|
19
|
-
end
|
20
|
-
|
21
|
-
expect(result).to be == [:a, :c, :a, :a, :b, :d]
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should fire immediately and then several times later" do
|
25
|
-
result = []
|
26
|
-
|
27
|
-
subject.every(0.7) { result << :a }
|
28
|
-
subject.every(2.3) { result << :b }
|
29
|
-
subject.now_and_every(1.3) { result << :c }
|
30
|
-
subject.now_and_every(2.4) { result << :d }
|
31
|
-
|
32
|
-
Timers::Wait.for(2.5) do |remaining|
|
33
|
-
subject.wait if subject.wait_interval < remaining
|
34
|
-
end
|
35
|
-
|
36
|
-
expect(result).to be == [:c, :d, :a, :c, :a, :a, :b, :d]
|
37
|
-
end
|
38
|
-
end
|
data/spec/timers/group_spec.rb
DELETED
@@ -1,260 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
|
-
|
8
|
-
RSpec.describe Timers::Group do
|
9
|
-
describe "#wait" do
|
10
|
-
it "calls the wait block with nil" do
|
11
|
-
called = false
|
12
|
-
|
13
|
-
subject.wait do |interval|
|
14
|
-
expect(interval).to be_nil
|
15
|
-
called = true
|
16
|
-
end
|
17
|
-
|
18
|
-
expect(called).to be true
|
19
|
-
end
|
20
|
-
|
21
|
-
it "calls the wait block with an interval" do
|
22
|
-
called = false
|
23
|
-
fired = false
|
24
|
-
|
25
|
-
subject.after(0.1) { fired = true }
|
26
|
-
|
27
|
-
subject.wait do |interval|
|
28
|
-
expect(interval).to be_within(TIMER_QUANTUM).of(0.1)
|
29
|
-
called = true
|
30
|
-
sleep 0.2
|
31
|
-
end
|
32
|
-
|
33
|
-
expect(called).to be true
|
34
|
-
expect(fired).to be true
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
it "sleeps until the next timer" do
|
39
|
-
interval = TIMER_QUANTUM * 2
|
40
|
-
started_at = Time.now
|
41
|
-
|
42
|
-
fired = false
|
43
|
-
subject.after(interval) { fired = true }
|
44
|
-
subject.wait
|
45
|
-
|
46
|
-
expect(fired).to be true
|
47
|
-
expect(Time.now - started_at).to be_within(TIMER_QUANTUM).of interval
|
48
|
-
end
|
49
|
-
|
50
|
-
it "fires instantly when next timer is in the past" do
|
51
|
-
fired = false
|
52
|
-
subject.after(TIMER_QUANTUM) { fired = true }
|
53
|
-
sleep(TIMER_QUANTUM * 2)
|
54
|
-
subject.wait
|
55
|
-
|
56
|
-
expect(fired).to be true
|
57
|
-
end
|
58
|
-
|
59
|
-
it "calculates the interval until the next timer should fire" do
|
60
|
-
interval = 0.1
|
61
|
-
|
62
|
-
subject.after(interval)
|
63
|
-
expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of interval
|
64
|
-
|
65
|
-
sleep(interval)
|
66
|
-
expect(subject.wait_interval).to be <= 0
|
67
|
-
end
|
68
|
-
|
69
|
-
it "fires timers in the correct order" do
|
70
|
-
result = []
|
71
|
-
|
72
|
-
subject.after(TIMER_QUANTUM * 2) { result << :two }
|
73
|
-
subject.after(TIMER_QUANTUM * 3) { result << :three }
|
74
|
-
subject.after(TIMER_QUANTUM * 1) { result << :one }
|
75
|
-
|
76
|
-
sleep TIMER_QUANTUM * 4
|
77
|
-
subject.fire
|
78
|
-
|
79
|
-
expect(result).to eq [:one, :two, :three]
|
80
|
-
end
|
81
|
-
|
82
|
-
it "raises TypeError if given an invalid time" do
|
83
|
-
expect do
|
84
|
-
subject.after(nil) { nil }
|
85
|
-
end.to raise_exception(TypeError)
|
86
|
-
end
|
87
|
-
|
88
|
-
describe "recurring timers" do
|
89
|
-
it "continues to fire the timers at each interval" do
|
90
|
-
result = []
|
91
|
-
|
92
|
-
subject.every(TIMER_QUANTUM * 2) { result << :foo }
|
93
|
-
|
94
|
-
sleep TIMER_QUANTUM * 3
|
95
|
-
subject.fire
|
96
|
-
expect(result).to eq [:foo]
|
97
|
-
|
98
|
-
sleep TIMER_QUANTUM * 5
|
99
|
-
subject.fire
|
100
|
-
expect(result).to eq [:foo, :foo]
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
it "calculates the proper interval to wait until firing" do
|
105
|
-
interval_ms = 25
|
106
|
-
|
107
|
-
subject.after(interval_ms / 1000.0)
|
108
|
-
|
109
|
-
expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of(interval_ms / 1000.0)
|
110
|
-
end
|
111
|
-
|
112
|
-
describe "pause and continue timers" do
|
113
|
-
before(:each) do
|
114
|
-
@interval = TIMER_QUANTUM * 2
|
115
|
-
|
116
|
-
@fired = false
|
117
|
-
@timer = subject.after(@interval) { @fired = true }
|
118
|
-
@fired2 = false
|
119
|
-
@timer2 = subject.after(@interval) { @fired2 = true }
|
120
|
-
end
|
121
|
-
|
122
|
-
it "does not fire when paused" do
|
123
|
-
@timer.pause
|
124
|
-
subject.wait
|
125
|
-
expect(@fired).to be false
|
126
|
-
end
|
127
|
-
|
128
|
-
it "fires when continued after pause" do
|
129
|
-
@timer.pause
|
130
|
-
subject.wait
|
131
|
-
@timer.resume
|
132
|
-
|
133
|
-
sleep @timer.interval
|
134
|
-
subject.wait
|
135
|
-
|
136
|
-
expect(@fired).to be true
|
137
|
-
end
|
138
|
-
|
139
|
-
it "can pause all timers at once" do
|
140
|
-
subject.pause
|
141
|
-
subject.wait
|
142
|
-
expect(@fired).to be false
|
143
|
-
expect(@fired2).to be false
|
144
|
-
end
|
145
|
-
|
146
|
-
it "can continue all timers at once" do
|
147
|
-
subject.pause
|
148
|
-
subject.wait
|
149
|
-
subject.resume
|
150
|
-
|
151
|
-
# We need to wait until we are sure both timers will fire, otherwise highly accurate clocks
|
152
|
-
# (e.g. JVM)may only fire the first timer, but not the second, because they are actually
|
153
|
-
# schedueled at different times.
|
154
|
-
sleep TIMER_QUANTUM * 2
|
155
|
-
subject.wait
|
156
|
-
|
157
|
-
expect(@fired).to be true
|
158
|
-
expect(@fired2).to be true
|
159
|
-
end
|
160
|
-
|
161
|
-
it "can fire the timer directly" do
|
162
|
-
fired = false
|
163
|
-
timer = subject.after(TIMER_QUANTUM * 1) { fired = true }
|
164
|
-
timer.pause
|
165
|
-
subject.wait
|
166
|
-
expect(fired).not_to be true
|
167
|
-
timer.resume
|
168
|
-
expect(fired).not_to be true
|
169
|
-
timer.fire
|
170
|
-
expect(fired).to be true
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
describe "delay timer" do
|
175
|
-
it "adds appropriate amount of time to timer" do
|
176
|
-
timer = subject.after(10)
|
177
|
-
timer.delay(5)
|
178
|
-
expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
describe "delay timer collection" do
|
183
|
-
it "delay on set adds appropriate amount of time to all timers" do
|
184
|
-
timer = subject.after(10)
|
185
|
-
timer2 = subject.after(20)
|
186
|
-
subject.delay(5)
|
187
|
-
expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
|
188
|
-
expect(timer2.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(25)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
describe "on delaying a timer" do
|
193
|
-
it "fires timers in the correct order" do
|
194
|
-
result = []
|
195
|
-
|
196
|
-
subject.after(TIMER_QUANTUM * 2) { result << :two }
|
197
|
-
subject.after(TIMER_QUANTUM * 3) { result << :three }
|
198
|
-
first = subject.after(TIMER_QUANTUM * 1) { result << :one }
|
199
|
-
first.delay(TIMER_QUANTUM * 3)
|
200
|
-
|
201
|
-
sleep TIMER_QUANTUM * 5
|
202
|
-
subject.fire
|
203
|
-
|
204
|
-
expect(result).to eq [:two, :three, :one]
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
describe "#inspect" do
|
209
|
-
it "before firing" do
|
210
|
-
fired = false
|
211
|
-
timer = subject.after(TIMER_QUANTUM * 5) { fired = true }
|
212
|
-
timer.pause
|
213
|
-
expect(fired).not_to be true
|
214
|
-
expect(timer.inspect).to match(/\A#<Timers::Timer:0x[\da-f]+ fires in [-\.\de]+ seconds>\Z/)
|
215
|
-
end
|
216
|
-
|
217
|
-
it "after firing" do
|
218
|
-
fired = false
|
219
|
-
timer = subject.after(TIMER_QUANTUM) { fired = true }
|
220
|
-
|
221
|
-
subject.wait
|
222
|
-
|
223
|
-
expect(fired).to be true
|
224
|
-
expect(timer.inspect).to match(/\A#<Timers::Timer:0x[\da-f]+ fired [-\.\de]+ seconds ago>\Z/)
|
225
|
-
end
|
226
|
-
|
227
|
-
it "recurring firing" do
|
228
|
-
result = []
|
229
|
-
timer = subject.every(TIMER_QUANTUM) { result << :foo }
|
230
|
-
|
231
|
-
subject.wait
|
232
|
-
expect(result).not_to be_empty
|
233
|
-
regex = /\A#<Timers::Timer:0x[\da-f]+ fires in [-\.\de]+ seconds, recurs every #{format("%0.2f", TIMER_QUANTUM)}>\Z/
|
234
|
-
expect(timer.inspect).to match(regex)
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
describe "#fires_in" do
|
239
|
-
let(:interval) { TIMER_QUANTUM * 2 }
|
240
|
-
|
241
|
-
it "calculates the interval until the next fire if it's recurring" do
|
242
|
-
timer = subject.every(interval) { true }
|
243
|
-
expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
|
244
|
-
end
|
245
|
-
|
246
|
-
context "when timer is not recurring" do
|
247
|
-
let!(:timer) { subject.after(interval) { true } }
|
248
|
-
|
249
|
-
it "calculates the interval until the next fire if it hasn't already fired" do
|
250
|
-
expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
|
251
|
-
end
|
252
|
-
|
253
|
-
it "calculates the interval since last fire if already fired" do
|
254
|
-
subject.wait
|
255
|
-
sleep(interval)
|
256
|
-
expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(0 - interval)
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
@@ -1,124 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
|
-
|
8
|
-
require "spec_helper"
|
9
|
-
|
10
|
-
# Event based timers:
|
11
|
-
|
12
|
-
# Serviced 31812 events in 2.39075272 seconds, 13306.320832794887 e/s.
|
13
|
-
# Thread ID: 7336700
|
14
|
-
# Fiber ID: 30106340
|
15
|
-
# Total: 2.384043
|
16
|
-
# Sort by: self_time
|
17
|
-
|
18
|
-
# %self total self wait child calls name
|
19
|
-
# 13.48 0.510 0.321 0.000 0.189 369133 Timers::Events::Handle#<=>
|
20
|
-
# 8.12 0.194 0.194 0.000 0.000 427278 Timers::Events::Handle#to_f
|
21
|
-
# 4.55 0.109 0.109 0.000 0.000 427278 Float#<=>
|
22
|
-
# 4.40 1.857 0.105 0.000 1.752 466376 *Timers::Events#bsearch
|
23
|
-
# 4.30 0.103 0.103 0.000 0.000 402945 Float#to_f
|
24
|
-
# 2.65 0.063 0.063 0.000 0.000 33812 Array#insert
|
25
|
-
# 2.64 1.850 0.063 0.000 1.787 33812 Timers::Events#schedule
|
26
|
-
# 2.40 1.930 0.057 0.000 1.873 33812 Timers::Timer#reset
|
27
|
-
# 1.89 1.894 0.045 0.000 1.849 31812 Timers::Timer#fire
|
28
|
-
# 1.69 1.966 0.040 0.000 1.926 31812 Timers::Events::Handle#fire
|
29
|
-
# 1.35 0.040 0.032 0.000 0.008 33812 Timers::Events::Handle#initialize
|
30
|
-
# 1.29 0.044 0.031 0.000 0.013 44451 Timers::Group#current_offset
|
31
|
-
|
32
|
-
# SortedSet based timers:
|
33
|
-
|
34
|
-
# Serviced 32516 events in 66.753277275 seconds, 487.1072288781219 e/s.
|
35
|
-
# Thread ID: 15995640
|
36
|
-
# Fiber ID: 38731780
|
37
|
-
# Total: 66.716394
|
38
|
-
# Sort by: self_time
|
39
|
-
|
40
|
-
# %self total self wait child calls name
|
41
|
-
# 54.73 49.718 36.513 0.000 13.205 57084873 Timers::Timer#<=>
|
42
|
-
# 23.74 65.559 15.841 0.000 49.718 32534 Array#sort!
|
43
|
-
# 19.79 13.205 13.205 0.000 0.000 57084873 Float#<=>
|
44
|
-
|
45
|
-
# Max out events performance (on my computer):
|
46
|
-
# Serviced 1142649 events in 11.194903921 seconds, 102068.70405115146 e/s.
|
47
|
-
|
48
|
-
RSpec.describe Timers::Group do
|
49
|
-
context "with profiler" do
|
50
|
-
if defined? RubyProf
|
51
|
-
before(:each) do
|
52
|
-
# Running RubyProf makes the code slightly slower.
|
53
|
-
RubyProf.start
|
54
|
-
puts "*** Running with RubyProf reduces performance ***"
|
55
|
-
end
|
56
|
-
|
57
|
-
after(:each) do
|
58
|
-
if RubyProf.running?
|
59
|
-
# file = arg.metadata[:description].gsub(/\s+/, '-')
|
60
|
-
|
61
|
-
result = RubyProf.stop
|
62
|
-
|
63
|
-
printer = RubyProf::FlatPrinter.new(result)
|
64
|
-
printer.print($stderr, min_percent: 1.0)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
it "runs efficiently" do
|
70
|
-
result = []
|
71
|
-
range = (1..500)
|
72
|
-
duration = 2.0
|
73
|
-
|
74
|
-
total = 0
|
75
|
-
range.each do |index|
|
76
|
-
offset = index.to_f / range.max
|
77
|
-
total += (duration / offset).floor
|
78
|
-
|
79
|
-
subject.every(index.to_f / range.max, :strict) { result << index }
|
80
|
-
end
|
81
|
-
|
82
|
-
subject.wait while result.size < total
|
83
|
-
|
84
|
-
rate = result.size.to_f / subject.current_offset
|
85
|
-
puts "Serviced #{result.size} events in #{subject.current_offset} seconds, #{rate} e/s."
|
86
|
-
|
87
|
-
expect(subject.current_offset).to be_within(20).percent_of(duration)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
it "runs efficiently at high volume" do
|
92
|
-
results = []
|
93
|
-
range = (1..300)
|
94
|
-
groups = (1..20)
|
95
|
-
duration = 11
|
96
|
-
|
97
|
-
timers = []
|
98
|
-
@mutex = Mutex.new
|
99
|
-
start = Time.now
|
100
|
-
groups.each do |gi|
|
101
|
-
timers << Thread.new {
|
102
|
-
result = []
|
103
|
-
timer = Timers::Group.new
|
104
|
-
total = 0
|
105
|
-
range.each do |ri|
|
106
|
-
offset = ri.to_f / range.max
|
107
|
-
total += (duration / offset).floor
|
108
|
-
timer.every(ri.to_f / range.max, :strict) { result << ri }
|
109
|
-
end
|
110
|
-
timer.wait while result.size < total
|
111
|
-
@mutex.synchronize { results += result }
|
112
|
-
|
113
|
-
}
|
114
|
-
end
|
115
|
-
timers.each { |t| t.join }
|
116
|
-
finish = Time.now
|
117
|
-
|
118
|
-
rate = results.size.to_f / ( runtime = finish - start )
|
119
|
-
|
120
|
-
puts "Serviced #{results.size} events in #{runtime} seconds, #{rate} e/s; across #{groups.max} timers."
|
121
|
-
|
122
|
-
expect(runtime).to be_within(20).percent_of(duration)
|
123
|
-
end
|
124
|
-
end
|
data/spec/timers/strict_spec.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
|
-
|
8
|
-
RSpec.describe Timers::Group do
|
9
|
-
it "should not diverge too much" do
|
10
|
-
fired = :not_fired_yet
|
11
|
-
count = 0
|
12
|
-
quantum = 0.01
|
13
|
-
|
14
|
-
start_offset = subject.current_offset
|
15
|
-
Timers::Timer.new(subject, quantum, :strict, start_offset) do |offset|
|
16
|
-
fired = offset
|
17
|
-
count += 1
|
18
|
-
end
|
19
|
-
|
20
|
-
iterations = 1000
|
21
|
-
subject.wait while count < iterations
|
22
|
-
|
23
|
-
# In my testing on the JVM, without the :strict recurring, I noticed 60ms of error here.
|
24
|
-
expect(fired - start_offset).to be_within(quantum).of(iterations * quantum)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should only fire 0-interval timer once per iteration" do
|
28
|
-
count = 0
|
29
|
-
|
30
|
-
start_offset = subject.current_offset
|
31
|
-
Timers::Timer.new(subject, 0, :strict, start_offset) do |offset, timer|
|
32
|
-
count += 1
|
33
|
-
end
|
34
|
-
|
35
|
-
subject.wait
|
36
|
-
|
37
|
-
expect(count).to be == 1
|
38
|
-
end
|
39
|
-
end
|
data/spec/timers/wait_spec.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
|
-
|
8
|
-
require "spec_helper"
|
9
|
-
require "timers/wait"
|
10
|
-
|
11
|
-
RSpec.describe Timers::Wait do
|
12
|
-
it "repeats until timeout expired" do
|
13
|
-
timeout = Timers::Wait.new(5)
|
14
|
-
count = 0
|
15
|
-
|
16
|
-
timeout.while_time_remaining do |remaining|
|
17
|
-
expect(remaining).to be_within(TIMER_QUANTUM).of(timeout.duration - count)
|
18
|
-
|
19
|
-
count += 1
|
20
|
-
sleep 1
|
21
|
-
end
|
22
|
-
|
23
|
-
expect(count).to eq(5)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "yields results as soon as possible" do
|
27
|
-
timeout = Timers::Wait.new(5)
|
28
|
-
|
29
|
-
result = timeout.while_time_remaining do |_remaining|
|
30
|
-
break :done
|
31
|
-
end
|
32
|
-
|
33
|
-
expect(result).to eq(:done)
|
34
|
-
end
|
35
|
-
end
|
data/timers.gemspec
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# This file is part of the "timers" project and released under the MIT license.
|
4
|
-
#
|
5
|
-
# Copyright, 2018, by Samuel Williams. All rights reserved.
|
6
|
-
#
|
7
|
-
|
8
|
-
require_relative 'lib/timers/version'
|
9
|
-
|
10
|
-
Gem::Specification.new do |spec|
|
11
|
-
spec.name = "timers"
|
12
|
-
spec.version = Timers::VERSION
|
13
|
-
spec.authors = ["Samuel Williams", "Tony Arcieri"]
|
14
|
-
spec.email = ["samuel@codeotaku.com", "bascule@gmail.com"]
|
15
|
-
spec.licenses = ["MIT"]
|
16
|
-
spec.homepage = "https://github.com/socketry/timers"
|
17
|
-
spec.summary = "Pure Ruby one-shot and periodic timers"
|
18
|
-
spec.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ")
|
19
|
-
Schedule procs to run after a certain time, or at periodic intervals,
|
20
|
-
using any API that accepts a timeout.
|
21
|
-
DESCRIPTION
|
22
|
-
|
23
|
-
spec.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
24
|
-
spec.executables = spec.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
25
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
26
|
-
spec.require_paths = ["lib"]
|
27
|
-
|
28
|
-
spec.required_ruby_version = '>= 2.2.1'
|
29
|
-
|
30
|
-
spec.add_development_dependency "bundler"
|
31
|
-
spec.add_development_dependency "rspec", "~> 3.6"
|
32
|
-
spec.add_development_dependency "rake"
|
33
|
-
end
|