timers 4.2.0 → 4.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|