class Observr::EventHandler::Darwin

FSEvents based event handler for Darwin/OSX

Uses ruby-fsevents (github.com/sandro/ruby-fsevent)

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/observr/event_handlers/darwin.rb, line 28
def initialize
  super
  self.latency = 0.2
end

Public Instance Methods

listen(monitored_paths) click to toggle source

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
refresh(monitored_paths) click to toggle source

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

detect_change(dir) click to toggle source

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
dirs_for(paths) click to toggle source

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
event_type(path) click to toggle source

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_for(dir) click to toggle source

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
on_change(dirs) click to toggle source

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_paths(paths) click to toggle source

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() click to toggle source

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