timers 4.1.2 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,12 @@
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
+
8
+ require "spec_helper"
9
+ require "ruby-prof" unless RUBY_PLATFORM =~ /java|rbx/
2
10
 
3
11
  # Event based timers:
4
12
 
@@ -39,58 +47,79 @@
39
47
  # Serviced 1142649 events in 11.194903921 seconds, 102068.70405115146 e/s.
40
48
 
41
49
  RSpec.describe Timers::Group do
42
- it "runs efficiently" do
43
- result = []
44
- range = (1..500)
45
- duration = 2.0
46
-
47
- total = 0
48
- range.each do |index|
49
- offset = index.to_f / range.max
50
- total += (duration / offset).floor
51
-
52
- subject.every(index.to_f / range.max, :strict) { result << index }
53
- end
54
-
55
- subject.wait while result.size < total
56
-
57
- rate = result.size.to_f / subject.current_offset
58
- puts "Serviced #{result.size} events in #{subject.current_offset} seconds, #{rate} e/s."
59
-
60
- expect(subject.current_offset).to be_within(TIMER_QUANTUM).of(duration)
61
- end
62
-
63
- # it "runs efficiently at high volume" do
64
- # results = []
65
- # range = (1..300)
66
- # groups = (1..20)
67
- # duration = 101
68
- #
69
- # timers = []
70
- # @mutex = Mutex.new
71
- # start = Time.now
72
- # groups.each do |gi|
73
- # timers << Thread.new {
74
- # result = []
75
- # timer = Timers::Group.new
76
- # total = 0
77
- # range.each do |ri|
78
- # offset = ri.to_f / range.max
79
- # total += (duration / offset).floor
80
- # timer.every(ri.to_f / range.max, :strict) { result << ri }
81
- # end
82
- # timer.wait while result.size < total
83
- # @mutex.synchronize { results += result }
84
- #
85
- # }
86
- # end
87
- # timers.each { |t| t.join }
88
- # finish = Time.now
89
- #
90
- # rate = results.size.to_f / ( runtime = finish - start )
91
- #
92
- # puts "Serviced #{results.size} events in #{runtime} seconds, #{rate} e/s; across #{groups.max} timers."
93
- #
94
- # expect(runtime).to be_within(TIMER_QUANTUM).of(duration)
95
- # end
50
+ context "with profiler" do
51
+ if defined? RubyProf
52
+ before(:each) do
53
+ # Running RubyProf makes the code slightly slower.
54
+ RubyProf.start
55
+ puts "*** Running with RubyProf reduces performance ***"
56
+ end
57
+
58
+ after(:each) do
59
+ if RubyProf.running?
60
+ # file = arg.metadata[:description].gsub(/\s+/, '-')
61
+
62
+ result = RubyProf.stop
63
+
64
+ printer = RubyProf::FlatPrinter.new(result)
65
+ printer.print($stderr, min_percent: 1.0)
66
+ end
67
+ end
68
+ end
69
+
70
+ it "runs efficiently" do
71
+ result = []
72
+ range = (1..500)
73
+ duration = 2.0
74
+
75
+ total = 0
76
+ range.each do |index|
77
+ offset = index.to_f / range.max
78
+ total += (duration / offset).floor
79
+
80
+ subject.every(index.to_f / range.max, :strict) { result << index }
81
+ end
82
+
83
+ subject.wait while result.size < total
84
+
85
+ rate = result.size.to_f / subject.current_offset
86
+ puts "Serviced #{result.size} events in #{subject.current_offset} seconds, #{rate} e/s."
87
+
88
+ expect(subject.current_offset).to be_within(20).percent_of(duration)
89
+ end
90
+ end
91
+
92
+ it "runs efficiently at high volume" do
93
+ results = []
94
+ range = (1..300)
95
+ groups = (1..20)
96
+ duration = 11
97
+
98
+ timers = []
99
+ @mutex = Mutex.new
100
+ start = Time.now
101
+ groups.each do |gi|
102
+ timers << Thread.new {
103
+ result = []
104
+ timer = Timers::Group.new
105
+ total = 0
106
+ range.each do |ri|
107
+ offset = ri.to_f / range.max
108
+ total += (duration / offset).floor
109
+ timer.every(ri.to_f / range.max, :strict) { result << ri }
110
+ end
111
+ timer.wait while result.size < total
112
+ @mutex.synchronize { results += result }
113
+
114
+ }
115
+ end
116
+ timers.each { |t| t.join }
117
+ finish = Time.now
118
+
119
+ rate = results.size.to_f / ( runtime = finish - start )
120
+
121
+ puts "Serviced #{results.size} events in #{runtime} seconds, #{rate} e/s; across #{groups.max} timers."
122
+
123
+ expect(runtime).to be_within(20).percent_of(duration)
124
+ end
96
125
  end
@@ -1,36 +1,41 @@
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
+ #
2
7
 
3
8
  RSpec.describe Timers::Group do
4
- it "should not diverge too much" do
5
- fired = :not_fired_yet
6
- count = 0
7
- quantum = 0.01
8
-
9
- start_offset = subject.current_offset
10
- Timers::Timer.new(subject, quantum, :strict, start_offset) do |offset|
11
- fired = offset
12
- count += 1
13
- end
14
-
15
- iterations = 1000
16
- subject.wait while count < iterations
17
-
18
- # In my testing on the JVM, without the :strict recurring, I noticed 60ms of error here.
19
- expect(fired - start_offset).to be_within(quantum).of(iterations * quantum)
20
- end
21
-
22
- it "should only fire once" do
23
- fired = :not_fired_yet
24
- count = 0
25
-
26
- start_offset = subject.current_offset
27
- Timers::Timer.new(subject, 0, :strict, start_offset) do |offset|
28
- fired = offset
29
- count += 1
30
- end
31
-
32
- subject.wait
33
-
34
- expect(count).to be == 1
35
- end
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 once" do
28
+ fired = :not_fired_yet
29
+ count = 0
30
+
31
+ start_offset = subject.current_offset
32
+ Timers::Timer.new(subject, 0, :strict, start_offset) do |offset|
33
+ fired = offset
34
+ count += 1
35
+ end
36
+
37
+ subject.wait
38
+
39
+ expect(count).to be == 1
40
+ end
36
41
  end
@@ -1,30 +1,35 @@
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
+ #
2
7
 
3
8
  require "spec_helper"
4
9
  require "timers/wait"
5
10
 
6
11
  RSpec.describe Timers::Wait do
7
- it "repeats until timeout expired" do
8
- timeout = Timers::Wait.new(5)
9
- count = 0
12
+ it "repeats until timeout expired" do
13
+ timeout = Timers::Wait.new(5)
14
+ count = 0
10
15
 
11
- timeout.while_time_remaining do |remaining|
12
- expect(remaining).to be_within(TIMER_QUANTUM).of(timeout.duration - count)
16
+ timeout.while_time_remaining do |remaining|
17
+ expect(remaining).to be_within(TIMER_QUANTUM).of(timeout.duration - count)
13
18
 
14
- count += 1
15
- sleep 1
16
- end
19
+ count += 1
20
+ sleep 1
21
+ end
17
22
 
18
- expect(count).to eq(5)
19
- end
23
+ expect(count).to eq(5)
24
+ end
20
25
 
21
- it "yields results as soon as possible" do
22
- timeout = Timers::Wait.new(5)
26
+ it "yields results as soon as possible" do
27
+ timeout = Timers::Wait.new(5)
23
28
 
24
- result = timeout.while_time_remaining do |_remaining|
25
- break :done
26
- end
29
+ result = timeout.while_time_remaining do |_remaining|
30
+ break :done
31
+ end
27
32
 
28
- expect(result).to eq(:done)
29
- end
33
+ expect(result).to eq(:done)
34
+ end
30
35
  end
@@ -1,26 +1,33 @@
1
- # -*- encoding: utf-8 -*-
2
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
+ #
3
7
 
4
- require File.expand_path("../lib/timers/version", __FILE__)
8
+ require_relative 'lib/timers/version'
5
9
 
6
- Gem::Specification.new do |gem|
7
- gem.name = "timers"
8
- gem.version = Timers::VERSION
9
- gem.authors = ["Tony Arcieri"]
10
- gem.email = ["bascule@gmail.com"]
11
- gem.licenses = ["MIT"]
12
- gem.homepage = "https://github.com/celluloid/timers"
13
- gem.summary = "Pure Ruby one-shot and periodic timers"
14
- gem.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ")
15
- Schedule procs to run after a certain time, or at periodic intervals,
16
- using any API that accepts a timeout.
17
- DESCRIPTION
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
18
22
 
19
- gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
20
- gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
21
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
22
- gem.require_paths = ["lib"]
23
- gem.add_runtime_dependency "hitimes"
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"]
24
27
 
25
- gem.add_development_dependency "bundler"
28
+ spec.required_ruby_version = '>= 2.2.1'
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.3"
31
+ spec.add_development_dependency "rspec", "~> 3.6"
32
+ spec.add_development_dependency "rake"
26
33
  end
metadata CHANGED
@@ -1,31 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timers
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.2
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
+ - Samuel Williams
7
8
  - Tony Arcieri
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2016-11-26 00:00:00.000000000 Z
12
+ date: 2018-11-06 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
- name: hitimes
15
+ name: bundler
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
- - - ">="
18
+ - - "~>"
18
19
  - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
20
+ version: '1.3'
21
+ type: :development
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
- - - ">="
25
+ - - "~>"
25
26
  - !ruby/object:Gem::Version
26
- version: '0'
27
+ version: '1.3'
27
28
  - !ruby/object:Gem::Dependency
28
- name: bundler
29
+ name: rspec
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '3.6'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '3.6'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
29
44
  requirement: !ruby/object:Gem::Requirement
30
45
  requirements:
31
46
  - - ">="
@@ -41,26 +56,22 @@ dependencies:
41
56
  description: Schedule procs to run after a certain time, or at periodic intervals,
42
57
  using any API that accepts a timeout.
43
58
  email:
59
+ - samuel@codeotaku.com
44
60
  - bascule@gmail.com
45
61
  executables: []
46
62
  extensions: []
47
63
  extra_rdoc_files: []
48
64
  files:
49
- - ".coveralls.yml"
50
65
  - ".gitignore"
51
66
  - ".rspec"
52
- - ".rubocop.yml"
53
- - ".ruby-version"
54
67
  - ".travis.yml"
55
- - AUTHORS.md
56
- - CHANGES.md
57
68
  - Gemfile
58
- - LICENSE
59
69
  - README.md
60
70
  - Rakefile
61
71
  - lib/timers.rb
62
72
  - lib/timers/events.rb
63
73
  - lib/timers/group.rb
74
+ - lib/timers/interval.rb
64
75
  - lib/timers/timer.rb
65
76
  - lib/timers/version.rb
66
77
  - lib/timers/wait.rb
@@ -73,7 +84,7 @@ files:
73
84
  - spec/timers/strict_spec.rb
74
85
  - spec/timers/wait_spec.rb
75
86
  - timers.gemspec
76
- homepage: https://github.com/celluloid/timers
87
+ homepage: https://github.com/socketry/timers
77
88
  licenses:
78
89
  - MIT
79
90
  metadata: {}
@@ -85,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
96
  requirements:
86
97
  - - ">="
87
98
  - !ruby/object:Gem::Version
88
- version: '0'
99
+ version: 2.2.1
89
100
  required_rubygems_version: !ruby/object:Gem::Requirement
90
101
  requirements:
91
102
  - - ">="
@@ -93,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
104
  version: '0'
94
105
  requirements: []
95
106
  rubyforge_project:
96
- rubygems_version: 2.5.2
107
+ rubygems_version: 2.7.7
97
108
  signing_key:
98
109
  specification_version: 4
99
110
  summary: Pure Ruby one-shot and periodic timers
@@ -1 +0,0 @@
1
- service-name: travis-pro
@@ -1,28 +0,0 @@
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