From 4cb49f2376d21a0c5db4f55c6110e48fdb2d3585 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Thu, 18 May 2017 13:18:09 -0700 Subject: [PATCH] Watcher: if we're already stale, no need to keep listening for changes --- lib/spring/watcher/listen.rb | 17 +++++++++++++++++ test/unit_test.rb | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/spring/watcher/listen.rb b/lib/spring/watcher/listen.rb index a925540..5984d28 100644 --- a/lib/spring/watcher/listen.rb +++ b/lib/spring/watcher/listen.rb @@ -21,6 +21,11 @@ class Listen < Abstract attr_reader :listener + def initialize(*) + super + @listener = nil + end + def start unless @listener @listener = ::Listen.to(*base_directories, latency: latency, &method(:changed)) @@ -35,6 +40,10 @@ def stop end end + def running? + @listener && @listener.processing? + end + def subjects_changed return unless @listener return unless @listener.respond_to?(:directories) @@ -54,6 +63,14 @@ def changed(modified, added, removed) end end + def mark_stale + super + + # May be called from listen thread which won't be happy + # about stopping itself, so stop from another thread. + Thread.new { stop }.join + end + def base_directories ([root] + files.reject { |f| f.start_with? "#{root}/" }.map { |f| File.expand_path("#{f}/..") } + diff --git a/test/unit_test.rb b/test/unit_test.rb index cd96c1e..435f00d 100644 --- a/test/unit_test.rb +++ b/test/unit_test.rb @@ -53,4 +53,22 @@ def watcher_class FileUtils.rmdir other_dir_2 end end + + test "stops listening when already stale" do + # Track when we're marked as stale. + on_stale_count = 0 + watcher.on_stale { on_stale_count += 1 } + + # Add a file to watch and start listening. + file = "#{@dir}/omg" + touch file, Time.now - 2.seconds + watcher.add file + watcher.start + assert watcher.running? + + # Touch bumps mtime and marks as stale which stops listener. + touch file, Time.now - 1.second + Timeout.timeout(1) { sleep 0.1 while watcher.running? } + assert_equal 1, on_stale_count + end end