Skip to content

Commit 0c3f0d5

Browse files
committed
Watcher: No need to keep checking mtimes if already stale
1 parent 87dc8ce commit 0c3f0d5

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

lib/spring/watcher/polling.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def start
3333
Thread.current.abort_on_exception = true
3434

3535
begin
36-
loop do
36+
until stale?
3737
Kernel.sleep latency
3838
check_stale
3939
end
@@ -42,6 +42,8 @@ def start
4242
"poller: aborted: #{e.class}: #{e}\n #{e.backtrace.join("\n ")}"
4343
end
4444
raise
45+
ensure
46+
@poller = nil
4547
end
4648
}
4749
end
@@ -55,6 +57,10 @@ def stop
5557
end
5658
end
5759

60+
def running?
61+
@poller && @poller.alive?
62+
end
63+
5864
def subjects_changed
5965
computed = compute_mtime
6066
debug { "subjects_changed: mtime #{@mtime} -> #{computed}" }

test/unit/watcher_test.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,55 @@ class PollingWatcherTest < Spring::Test::WatcherTest
66
def watcher_class
77
Spring::Watcher::Polling
88
end
9+
10+
test "skips staleness checks if already stale" do
11+
class << watcher
12+
attr_reader :checked_when_stale_count
13+
attr_reader :checked_when_not_stale_count
14+
15+
def check_stale
16+
@checked_when_stale_count = 0 unless defined? @checked_when_stale_count
17+
@checked_when_not_stale_count = 0 unless defined? @checked_when_not_stale_count
18+
19+
if stale?
20+
@checked_when_stale_count += 1
21+
else
22+
@checked_when_not_stale_count += 1
23+
end
24+
25+
super
26+
end
27+
28+
# Wait for the poller thread to finish.
29+
def join
30+
@poller.join if @poller
31+
end
32+
end
33+
34+
# Track when we're marked as stale.
35+
on_stale_count = 0
36+
watcher.on_stale { on_stale_count += 1 }
37+
38+
# Add a file to watch and start polling.
39+
file = "#{@dir}/omg"
40+
touch file, Time.now - 2.seconds
41+
watcher.add file
42+
watcher.start
43+
assert watcher.running?
44+
45+
# First touch bumps mtime and marks as stale.
46+
touch file, Time.now - 1.second
47+
Timeout.timeout(1) { watcher.join }
48+
assert !watcher.running?
49+
assert_equal 0, watcher.checked_when_stale_count
50+
assert_equal 1, watcher.checked_when_not_stale_count
51+
assert_equal 1, on_stale_count
52+
53+
# Second touch skips mtime check because it's already stale.
54+
touch file, Time.now
55+
sleep 1
56+
assert_equal 0, watcher.checked_when_stale_count
57+
assert_equal 1, watcher.checked_when_not_stale_count
58+
assert_equal 1, on_stale_count
59+
end
960
end

0 commit comments

Comments
 (0)