class Observr::EventHandler::Darwin
FSEvents
based event handler for Darwin/OSX
Uses ruby-fsevents (github.com/sandro/ruby-fsevent)
Public Class Methods
# File lib/observr/event_handlers/darwin.rb, line 28 def initialize super self.latency = 0.2 end
Public Instance Methods
Enter listening loop. Will block control flow until application is explicitly stopped/killed.
@return [undefined]
# File lib/observr/event_handlers/darwin.rb, line 38 def listen(monitored_paths) register_paths(monitored_paths) start end
Rebuild file bindings. Will detach all current bindings, and reattach the ‘monitored_paths`
@param [Array<Pathname>] monitored_paths
list of paths the application is currently monitoring.
@return [undefined]
# File lib/observr/event_handlers/darwin.rb, line 51 def refresh(monitored_paths) register_paths(monitored_paths) restart end
Private Instance Methods
Detected latest updated file within given directory
@param [Pathname, String] dir
directory reporting event
@return [Array(Pathname, Symbol)] path and type
path to updated file and event type
# File lib/observr/event_handlers/darwin.rb, line 78 def detect_change(dir) paths = monitored_paths_for(dir) type = nil path = paths.find {|path| type = event_type(path) } FSEvents.debug("event detection error") if type.nil? update_reference_times [path, type] end
Directories for paths
A unique list of directories containing given paths
@param [Array<Pathname>] paths
@return [Array<Pathname>] dirs
# File lib/observr/event_handlers/darwin.rb, line 139 def dirs_for(paths) paths.map {|path| path.dirname.to_s }.uniq end
Detect type of event for path, if any
Path times (atime, mtime, ctime) are compared to stored references. If any is more recent, the event is reported as a symbol.
@param [Pathname] path
@return [Symbol, nil] event type
Event type if detected, nil otherwise. Symbol is on of :deleted, :modified, :accessed, :changed
# File lib/observr/event_handlers/darwin.rb, line 100 def event_type(path) return :deleted if !path.exist? return :modified if path.mtime > @reference_times[path][:mtime] return :accessed if path.atime > @reference_times[path][:atime] return :changed if path.ctime > @reference_times[path][:ctime] nil end
Monitored paths within given dir
@param [Pathname, String] dir
@return [Array<Pathname>] monitored_paths
# File lib/observr/event_handlers/darwin.rb, line 114 def monitored_paths_for(dir) dir = Pathname(dir).expand_path @paths.select {|path| path.dirname.expand_path == dir } end
Callback. Called on file change event. Delegates to {Controller#update}, passing in path and event type
@return [undefined]
# File lib/observr/event_handlers/darwin.rb, line 63 def on_change(dirs) dirs.each do |dir| path, type = detect_change(dir) notify(path, type) unless path.nil? end end
Register watches for paths
@param [Array<Pathname>] paths
@return [undefined]
# File lib/observr/event_handlers/darwin.rb, line 125 def register_paths(paths) @paths = paths watch_directories(dirs_for(@paths)) update_reference_times end
Update reference times for registered paths
@return [undefined]
# File lib/observr/event_handlers/darwin.rb, line 147 def update_reference_times @reference_times = {} now = Time.now @paths.each do |path| @reference_times[path] = {} @reference_times[path][:atime] = now @reference_times[path][:mtime] = now @reference_times[path][:ctime] = now end end