timers 4.2.0 → 4.3.3
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 +58 -56
- data/lib/timers/group.rb +42 -27
- data/lib/timers/interval.rb +20 -5
- data/lib/timers/priority_heap.rb +174 -0
- data/lib/timers/timer.rb +63 -45
- data/lib/timers/version.rb +21 -6
- data/lib/timers/wait.rb +28 -13
- metadata +25 -51
- data/.gitignore +0 -17
- data/.rspec +0 -3
- data/.travis.yml +0 -19
- data/Gemfile +0 -15
- data/README.md +0 -149
- data/Rakefile +0 -6
- data/spec/spec_helper.rb +0 -38
- 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 -125
- data/spec/timers/strict_spec.rb +0 -41
- data/spec/timers/wait_spec.rb +0 -35
- data/timers.gemspec +0 -33
@@ -1,125 +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 "ruby-prof" unless RUBY_PLATFORM =~ /java|rbx/
|
10
|
-
|
11
|
-
# Event based timers:
|
12
|
-
|
13
|
-
# Serviced 31812 events in 2.39075272 seconds, 13306.320832794887 e/s.
|
14
|
-
# Thread ID: 7336700
|
15
|
-
# Fiber ID: 30106340
|
16
|
-
# Total: 2.384043
|
17
|
-
# Sort by: self_time
|
18
|
-
|
19
|
-
# %self total self wait child calls name
|
20
|
-
# 13.48 0.510 0.321 0.000 0.189 369133 Timers::Events::Handle#<=>
|
21
|
-
# 8.12 0.194 0.194 0.000 0.000 427278 Timers::Events::Handle#to_f
|
22
|
-
# 4.55 0.109 0.109 0.000 0.000 427278 Float#<=>
|
23
|
-
# 4.40 1.857 0.105 0.000 1.752 466376 *Timers::Events#bsearch
|
24
|
-
# 4.30 0.103 0.103 0.000 0.000 402945 Float#to_f
|
25
|
-
# 2.65 0.063 0.063 0.000 0.000 33812 Array#insert
|
26
|
-
# 2.64 1.850 0.063 0.000 1.787 33812 Timers::Events#schedule
|
27
|
-
# 2.40 1.930 0.057 0.000 1.873 33812 Timers::Timer#reset
|
28
|
-
# 1.89 1.894 0.045 0.000 1.849 31812 Timers::Timer#fire
|
29
|
-
# 1.69 1.966 0.040 0.000 1.926 31812 Timers::Events::Handle#fire
|
30
|
-
# 1.35 0.040 0.032 0.000 0.008 33812 Timers::Events::Handle#initialize
|
31
|
-
# 1.29 0.044 0.031 0.000 0.013 44451 Timers::Group#current_offset
|
32
|
-
|
33
|
-
# SortedSet based timers:
|
34
|
-
|
35
|
-
# Serviced 32516 events in 66.753277275 seconds, 487.1072288781219 e/s.
|
36
|
-
# Thread ID: 15995640
|
37
|
-
# Fiber ID: 38731780
|
38
|
-
# Total: 66.716394
|
39
|
-
# Sort by: self_time
|
40
|
-
|
41
|
-
# %self total self wait child calls name
|
42
|
-
# 54.73 49.718 36.513 0.000 13.205 57084873 Timers::Timer#<=>
|
43
|
-
# 23.74 65.559 15.841 0.000 49.718 32534 Array#sort!
|
44
|
-
# 19.79 13.205 13.205 0.000 0.000 57084873 Float#<=>
|
45
|
-
|
46
|
-
# Max out events performance (on my computer):
|
47
|
-
# Serviced 1142649 events in 11.194903921 seconds, 102068.70405115146 e/s.
|
48
|
-
|
49
|
-
RSpec.describe Timers::Group do
|
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
|
125
|
-
end
|
data/spec/timers/strict_spec.rb
DELETED
@@ -1,41 +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 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
|
41
|
-
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", "~> 1.3"
|
31
|
-
spec.add_development_dependency "rspec", "~> 3.6"
|
32
|
-
spec.add_development_dependency "rake"
|
33
|
-
end
|