diff options
author | Sean Griffin <sean@seantheprogrammer.com> | 2016-06-17 10:19:56 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-17 10:19:56 -0400 |
commit | 30dd8b2cb0913b2ecc94d2b1d9e29b15e5913f71 (patch) | |
tree | 17fa12921aa5b9817458be4c3639ad526ff5abc1 /activesupport/lib | |
parent | 58b70b4ed562f0086314d15bb9efcc0fec573b0f (diff) | |
parent | 844af9fa7c18a0ee3316d6cf1289b144d48d84d7 (diff) | |
download | rails-30dd8b2cb0913b2ecc94d2b1d9e29b15e5913f71.tar.gz rails-30dd8b2cb0913b2ecc94d2b1d9e29b15e5913f71.tar.bz2 rails-30dd8b2cb0913b2ecc94d2b1d9e29b15e5913f71.zip |
Merge pull request #25302 from schneems/schneems/evented-file-boot-at-check-time-master
EventedFileUpdateChecker boots once per process
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/evented_file_update_checker.rb | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/activesupport/lib/active_support/evented_file_update_checker.rb b/activesupport/lib/active_support/evented_file_update_checker.rb index 21fdf7bb80..a2dcf31132 100644 --- a/activesupport/lib/active_support/evented_file_update_checker.rb +++ b/activesupport/lib/active_support/evented_file_update_checker.rb @@ -3,6 +3,33 @@ require 'pathname' require 'concurrent/atomic/atomic_boolean' module ActiveSupport + # Allows you to "listen" to changes in a file system. + # The evented file updater does not hit disk when checking for updates + # instead it uses platform specific file system events to trigger a change + # in state. + # + # The file checker takes an array of files to watch or a hash specifying directories + # and file extensions to watch. It also takes a block that is called when + # EventedFileUpdateChecker#execute is run or when EventedFileUpdateChecker#execute_if_updated + # is run and there have been changes to the file system. + # + # Note: Forking will cause the first call to `updated?` to return `true`. + # + # Example: + # + # checker = EventedFileUpdateChecker.new(["/tmp/foo"], -> { puts "changed" }) + # checker.updated? + # # => false + # checker.execute_if_updated + # # => nil + # + # FileUtils.touch("/tmp/foo") + # + # checker.updated? + # # => true + # checker.execute_if_updated + # # => "changed" + # class EventedFileUpdateChecker #:nodoc: all def initialize(files, dirs = {}, &block) @ph = PathHelper.new @@ -13,11 +40,13 @@ module ActiveSupport @dirs[@ph.xpath(dir)] = Array(exts).map { |ext| @ph.normalize_extension(ext) } end - @block = block - @updated = Concurrent::AtomicBoolean.new(false) - @lcsp = @ph.longest_common_subpath(@dirs.keys) + @block = block + @updated = Concurrent::AtomicBoolean.new(false) + @lcsp = @ph.longest_common_subpath(@dirs.keys) + @pid = Process.pid + @boot_mutex = Mutex.new - if (dtw = directories_to_watch).any? + if (@dtw = directories_to_watch).any? # Loading listen triggers warnings. These are originated by a legit # usage of attr_* macros for private attributes, but adds a lot of noise # to our test suite. Thus, we lazy load it and disable warnings locally. @@ -28,11 +57,18 @@ module ActiveSupport raise LoadError, "Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile", e.backtrace end end - Listen.to(*dtw, &method(:changed)).start end + boot! end def updated? + @boot_mutex.synchronize do + if @pid != Process.pid + boot! + @pid = Process.pid + @updated.make_true + end + end @updated.true? end @@ -50,6 +86,9 @@ module ActiveSupport end private + def boot! + Listen.to(*@dtw, &method(:changed)).start + end def changed(modified, added, removed) unless updated? |