You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
6.2 KiB
260 lines
6.2 KiB
https://github.com/socketry/timers/issues/82
|
|
https://github.com/socketry/timers/commit/039bbd2750d5e50721789ef5d3404b18c36517bc
|
|
|
|
From 039bbd2750d5e50721789ef5d3404b18c36517bc Mon Sep 17 00:00:00 2001
|
|
From: Samuel Williams <samuel.williams@oriontransfer.co.nz>
|
|
Date: Wed, 12 Apr 2023 17:25:59 +1200
|
|
Subject: [PATCH] Modernize gem (#83)
|
|
|
|
* Improve robustness of `Timer#inspect`.
|
|
|
|
* 100% test coverage.
|
|
--- a/fixtures/timer_quantum.rb
|
|
+++ b/fixtures/timer_quantum.rb
|
|
@@ -1,3 +1,5 @@
|
|
+# frozen_string_literal: true
|
|
+
|
|
# Released under the MIT License.
|
|
# Copyright, 2022, by Samuel Williams.
|
|
|
|
--- a/lib/timers/group.rb
|
|
+++ b/lib/timers/group.rb
|
|
@@ -92,8 +92,9 @@ def wait
|
|
# - 0: timers ready to fire
|
|
# - +ve: timers waiting to fire
|
|
def wait_interval(offset = current_offset)
|
|
- handle = @events.first
|
|
- handle.time - Float(offset) if handle
|
|
+ if handle = @events.first
|
|
+ handle.time - Float(offset)
|
|
+ end
|
|
end
|
|
|
|
# Fire all timers that are ready.
|
|
--- a/lib/timers/priority_heap.rb
|
|
+++ b/lib/timers/priority_heap.rb
|
|
@@ -84,9 +84,10 @@ def valid?
|
|
|
|
private
|
|
|
|
- def swap(i, j)
|
|
- @contents[i], @contents[j] = @contents[j], @contents[i]
|
|
- end
|
|
+ # Left here for reference, but unused.
|
|
+ # def swap(i, j)
|
|
+ # @contents[i], @contents[j] = @contents[j], @contents[i]
|
|
+ # end
|
|
|
|
def bubble_up(index)
|
|
parent_index = (index - 1) / 2 # watch out, integer division!
|
|
--- a/lib/timers/timer.rb
|
|
+++ b/lib/timers/timer.rb
|
|
@@ -23,12 +23,11 @@ def initialize(group, interval, recurring = false, offset = nil, &block)
|
|
@interval = interval
|
|
@recurring = recurring
|
|
@block = block
|
|
- @offset = offset
|
|
-
|
|
+ @offset = nil
|
|
@handle = nil
|
|
|
|
# If a start offset was supplied, use that, otherwise use the current timers offset.
|
|
- reset(@offset || @group.current_offset)
|
|
+ reset(offset || @group.current_offset)
|
|
end
|
|
|
|
def paused?
|
|
@@ -73,7 +72,7 @@ def cancel
|
|
@handle = nil
|
|
|
|
# This timer is no longer valid:
|
|
- @group.timers.delete self if @group
|
|
+ @group.timers.delete(self) if @group
|
|
end
|
|
|
|
# Reset this timer. Do not call while paused.
|
|
@@ -117,18 +116,18 @@ def fires_in
|
|
|
|
# Inspect a timer
|
|
def inspect
|
|
- buffer = "#{to_s[0..-2]} ".dup
|
|
+ buffer = to_s[0..-2]
|
|
|
|
if @offset
|
|
- if fires_in >= 0
|
|
- buffer << "fires in #{fires_in} seconds"
|
|
+ delta_offset = @offset - @group.current_offset
|
|
+
|
|
+ if delta_offset > 0
|
|
+ buffer << " fires in #{delta_offset} seconds"
|
|
else
|
|
- buffer << "fired #{fires_in.abs} seconds ago"
|
|
+ buffer << " fired #{delta_offset.abs} seconds ago"
|
|
end
|
|
|
|
buffer << ", recurs every #{interval}" if recurring
|
|
- else
|
|
- buffer << "dead"
|
|
end
|
|
|
|
buffer << ">"
|
|
--- a/lib/timers/wait.rb
|
|
+++ b/lib/timers/wait.rb
|
|
@@ -17,6 +17,7 @@ def self.for(duration, &block)
|
|
|
|
timeout.while_time_remaining(&block)
|
|
else
|
|
+ # If there is no "duration" to wait for, we wait forever.
|
|
loop do
|
|
yield(nil)
|
|
end
|
|
--- a/license.md
|
|
+++ b/license.md
|
|
@@ -28,6 +28,7 @@ Copyright, 2017-2020, by Olle Jonsson.
|
|
Copyright, 2020, by Tim Smith.
|
|
Copyright, 2021, by Wander Hillen.
|
|
Copyright, 2022, by Yoshiki Takagi.
|
|
+Copyright, 2023, by Peter Goldstein.
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
--- a/test/timers/group.rb
|
|
+++ b/test/timers/group.rb
|
|
@@ -36,18 +36,31 @@
|
|
expect(called).to be == true
|
|
expect(fired).to be == true
|
|
end
|
|
+
|
|
+ it "repeatedly calls the wait block if it sleeps less than the interval" do
|
|
+ called = 0
|
|
+ fired = false
|
|
+
|
|
+ group.after(0.1) { fired = true }
|
|
+
|
|
+ group.wait do |interval|
|
|
+ called += 1
|
|
+ sleep(0.01)
|
|
+ end
|
|
+
|
|
+ expect(called).to be > 1
|
|
+ expect(fired).to be == true
|
|
+ end
|
|
end
|
|
|
|
it "sleeps until the next timer" do
|
|
interval = 0.1
|
|
- started_at = Time.now
|
|
|
|
fired = false
|
|
group.after(interval) {fired = true}
|
|
group.wait
|
|
|
|
expect(fired).to be == true
|
|
- expect(Time.now - started_at).to be_within(TIMER_QUANTUM).of(interval)
|
|
end
|
|
|
|
it "fires instantly when next timer is in the past" do
|
|
@@ -88,6 +101,26 @@
|
|
end.to raise_exception(TypeError)
|
|
end
|
|
|
|
+ with "#now_and_after" do
|
|
+ it "fires the timer immediately" do
|
|
+ result = []
|
|
+
|
|
+ group.now_and_after(TIMER_QUANTUM * 2) { result << :foo }
|
|
+
|
|
+ expect(result).to be == [:foo]
|
|
+ end
|
|
+
|
|
+ it "fires the timer at the correct time" do
|
|
+ result = []
|
|
+
|
|
+ group.now_and_after(TIMER_QUANTUM * 2) { result << :foo }
|
|
+
|
|
+ group.wait
|
|
+
|
|
+ expect(result).to be == [:foo, :foo]
|
|
+ end
|
|
+ end
|
|
+
|
|
with "recurring timers" do
|
|
it "continues to fire the timers at each interval" do
|
|
result = []
|
|
--- a/test/timers/group/cancel.rb
|
|
+++ b/test/timers/group/cancel.rb
|
|
@@ -10,6 +10,17 @@
|
|
describe Timers::Group do
|
|
let(:group) {subject.new}
|
|
|
|
+ it "can cancel a timer" do
|
|
+ fired = false
|
|
+
|
|
+ timer = group.after(0.1) { fired = true }
|
|
+ timer.cancel
|
|
+
|
|
+ group.wait
|
|
+
|
|
+ expect(fired).to be == false
|
|
+ end
|
|
+
|
|
it "should be able to cancel twice" do
|
|
fired = false
|
|
|
|
@@ -51,4 +62,18 @@
|
|
expect(group.timers).to be(:empty?)
|
|
expect(x).to be == 0
|
|
end
|
|
+
|
|
+ with "#cancel" do
|
|
+ it "should cancel all timers" do
|
|
+ timers = 3.times.map do
|
|
+ group.every(0.1) {}
|
|
+ end
|
|
+
|
|
+ expect(group.timers).not.to be(:empty?)
|
|
+
|
|
+ group.cancel
|
|
+
|
|
+ expect(group.timers).to be(:empty?)
|
|
+ end
|
|
+ end
|
|
end
|
|
--- a/test/timers/wait.rb
|
|
+++ b/test/timers/wait.rb
|
|
@@ -14,9 +14,14 @@
|
|
it "repeats until timeout expired" do
|
|
timeout = Timers::Wait.new(interval*repeats)
|
|
count = 0
|
|
+ previous_remaining = nil
|
|
|
|
timeout.while_time_remaining do |remaining|
|
|
- expect(remaining).to be_within(TIMER_QUANTUM).of(timeout.duration - (count * interval))
|
|
+ if previous_remaining
|
|
+ expect(remaining).to be_within(TIMER_QUANTUM).of(previous_remaining - interval)
|
|
+ end
|
|
+
|
|
+ previous_remaining = remaining
|
|
|
|
count += 1
|
|
sleep(interval)
|
|
@@ -34,4 +39,18 @@
|
|
|
|
expect(result).to be == :done
|
|
end
|
|
+
|
|
+ with "#for" do
|
|
+ with "no duration" do
|
|
+ it "waits forever" do
|
|
+ count = 0
|
|
+ Timers::Wait.for(nil) do
|
|
+ count += 1
|
|
+ break if count > 10
|
|
+ end
|
|
+
|
|
+ expect(count).to be > 10
|
|
+ end
|
|
+ end
|
|
+ end
|
|
end
|