Class: Listen::Adapter

Inherits:
Object
  • Object
show all
Defined in:
lib/listen/adapter.rb

Constant Summary collapse

DEFAULT_LATENCY =

The default delay between checking for changes.

0.1
POLLING_FALLBACK_MESSAGE =

The default warning message when falling back to polling adapter.

"WARNING: Listen has fallen back to polling, learn more at https://github.com/guard/listen#fallback."

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(directories, options = {}) {|changed_dirs, options| ... } ⇒ Listen::Adapter

Initializes the adapter.

Parameters:

  • directories (String, Array<String>)

    the directories to watch

  • options (Hash) (defaults to: {})

    the adapter options

Options Hash (options):

  • latency (Float)

    the delay between checking for changes in seconds

Yields:

  • (changed_dirs, options)

    callback Callback called when a change happens

Yield Parameters:

  • changed_dirs (Array<String>)

    the changed directories

  • options (Hash)

    callback options (like :recursive => true)



60
61
62
63
64
65
66
67
68
69
# File 'lib/listen/adapter.rb', line 60

def initialize(directories, options = {}, &callback)
  @directories  = Array(directories)
  @callback     = callback
  @latency    ||= DEFAULT_LATENCY
  @latency      = options[:latency] if options[:latency]
  @paused       = false
  @mutex        = Mutex.new
  @changed_dirs = Set.new
  @turnstile    = Turnstile.new
end

Instance Attribute Details

#directoriesObject

Returns the value of attribute directories.



8
9
10
# File 'lib/listen/adapter.rb', line 8

def directories
  @directories
end

#latencyObject

Returns the value of attribute latency.



8
9
10
# File 'lib/listen/adapter.rb', line 8

def latency
  @latency
end

#pausedObject

Returns the value of attribute paused.



8
9
10
# File 'lib/listen/adapter.rb', line 8

def paused
  @paused
end

Class Method Details

.select_and_initialize(directories, options = {}) {|changed_dirs, options| ... } ⇒ Listen::Adapter

Selects the appropriate adapter implementation for the current OS and initializes it.

Parameters:

  • directories (String, Array<String>)

    the directories to watch

  • options (Hash) (defaults to: {})

    the adapter options

Options Hash (options):

  • force_polling (Boolean)

    to force polling or not

  • polling_fallback_message (String, Boolean)

    to change polling fallback message or remove it

  • latency (Float)

    the delay between checking for changes in seconds

Yields:

  • (changed_dirs, options)

    callback Callback called when a change happens

Yield Parameters:

  • changed_dirs (Array<String>)

    the changed directories

  • options (Hash)

    callback options (like :recursive => true)

Returns:



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/listen/adapter.rb', line 31

def self.select_and_initialize(directories, options = {}, &callback)
  return Adapters::Polling.new(directories, options, &callback) if options.delete(:force_polling)

  if Adapters::Darwin.usable_and_works?(directories, options)
    Adapters::Darwin.new(directories, options, &callback)
  elsif Adapters::Linux.usable_and_works?(directories, options)
    Adapters::Linux.new(directories, options, &callback)
  elsif Adapters::Windows.usable_and_works?(directories, options)
    Adapters::Windows.new(directories, options, &callback)
  else
    unless options[:polling_fallback_message] == false
      Kernel.warn(options[:polling_fallback_message] || POLLING_FALLBACK_MESSAGE)
    end
    Adapters::Polling.new(directories, options, &callback)
  end
end

.usable_and_works?(directories, options = {}) ⇒ Boolean

Checks if the adapter is usable and works on the current OS.

Parameters:

  • directories (String, Array<String>)

    the directories to watch

  • options (Hash) (defaults to: {})

    the adapter options

Options Hash (options):

  • latency (Float)

    the delay between checking for changes in seconds

Returns:

  • (Boolean)

    whether usable and work or not



101
102
103
# File 'lib/listen/adapter.rb', line 101

def self.usable_and_works?(directories, options = {})
  usable? && Array(directories).all? { |d| works?(d, options) }
end

.works?(directory, options = {}) ⇒ Boolean

Note:

This test takes some time depending the adapter latency.

Runs a tests to determine if the adapter can actually pick up changes in a given directory and returns the result.

Parameters:

  • directory (String, Pathname)

    the directory to watch

  • options (Hash) (defaults to: {})

    the adapter options

Options Hash (options):

  • latency (Float)

    the delay between checking for changes in seconds

Returns:

  • (Boolean)

    whether the adapter works or not



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/listen/adapter.rb', line 116

def self.works?(directory, options = {})
  work = false
  test_file = "#{directory}/.listen_test"
  callback = lambda { |changed_dirs, options| work = true }
  adapter  = self.new(directory, options, &callback)
  adapter.start(false)

  FileUtils.touch(test_file)

  t = Thread.new { sleep(adapter.latency * 5); adapter.stop }

  adapter.wait_for_callback
  work
ensure
  Thread.kill(t) if t
  FileUtils.rm(test_file) if File.exists?(test_file)
  adapter.stop
end

Instance Method Details

#start(blocking = true) ⇒ Object

Starts the adapter.

Parameters:

  • blocking (Boolean) (defaults to: true)

    whether or not to block the current thread after starting



75
76
77
# File 'lib/listen/adapter.rb', line 75

def start(blocking = true)
  @stop = false
end

#stopObject

Stops the adapter.



81
82
83
84
# File 'lib/listen/adapter.rb', line 81

def stop
  @stop = true
  @turnstile.signal # ensure no thread is blocked
end

#wait_for_callbackObject

Blocks the main thread until the poll thread calls the callback.



89
90
91
# File 'lib/listen/adapter.rb', line 89

def wait_for_callback
  @turnstile.wait unless @paused
end