Class: DirectoryWatcher::Scanner

Inherits:
Object
  • Object
show all
Defined in:
lib/directory_watcher/scanner.rb

Overview

The Scanner is responsible for polling the watched directory at a regular interval and generating events when files are modified, added or removed. These events are passed to the DirectoryWatcher which notifies the registered observers.

The Scanner is a pure Ruby class, and as such it works across all Ruby interpreters on the major platforms. This also means that it can be processor intensive for large numbers of files or very fast update intervals. Your mileage will vary, but it is something to keep an eye on.

Direct Known Subclasses

CoolioScanner, EmScanner, RevScanner

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ Scanner

call-seq:

Scanner.new { |events| block }

Create a thread-based scanner that will generate file events and pass those events (as an array) to the given block.



25
26
27
28
29
# File 'lib/directory_watcher/scanner.rb', line 25

def initialize( &block )
  @events = []
  @thread = nil
  @notify = block;
end

Instance Attribute Details

#filesObject

Returns the value of attribute files.



17
18
19
# File 'lib/directory_watcher/scanner.rb', line 17

def files
  @files
end

#globObject

Returns the value of attribute glob.



14
15
16
# File 'lib/directory_watcher/scanner.rb', line 14

def glob
  @glob
end

#intervalObject

Returns the value of attribute interval.



15
16
17
# File 'lib/directory_watcher/scanner.rb', line 15

def interval
  @interval
end

#stableObject

Returns the value of attribute stable.



16
17
18
# File 'lib/directory_watcher/scanner.rb', line 16

def stable
  @stable
end

Instance Method Details

#join(limit = nil) ⇒ Object

call-seq:

join( limit = nil )

If the scanner thread is running, the calling thread will suspend execution and run the scanner thread. This method does not return until the scanner thread is stopped or until limit seconds have passed.

If the scanner thread is not running, this method returns immediately with nil.



86
87
88
89
# File 'lib/directory_watcher/scanner.rb', line 86

def join( limit = nil )
  return unless running?
  @thread.join limit
end

#reset(pre_load = false) ⇒ Object

call-seq:

reset( pre_load = false )

Reset the scanner state by clearing the stored file list. Passing true to this method will cause the file list to be pre-loaded after it has been cleared effectively skipping the initial round of file added events that would normally be generated.



71
72
73
74
# File 'lib/directory_watcher/scanner.rb', line 71

def reset( pre_load = false )
  @events.clear
  @files = (pre_load ? scan_files : Hash.new)
end

#run_onceObject

Performs exactly one scan of the directory for file changes and notifies the observers.



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/directory_watcher/scanner.rb', line 94

def run_once
  files = scan_files
  keys = [files.keys, @files.keys]  # current files, previous files

  find_added(files, *keys)
  find_modified(files, *keys)
  find_removed(*keys)

  notify
  @files = files    # store the current file list for the next iteration
  self
end

#running?Boolean

Returns true if the scanner is currently running. Returns false if this is not the case.

Returns:

  • (Boolean)


34
35
36
# File 'lib/directory_watcher/scanner.rb', line 34

def running?
  !@thread.nil?
end

#startObject

Start the scanner thread. If the scanner is already running, this method will return without taking any action.



41
42
43
44
45
46
47
# File 'lib/directory_watcher/scanner.rb', line 41

def start
  return if running?

  @stop = false
  @thread = Thread.new(self) {|scanner| scanner.__send__ :run_loop}
  self
end

#stopObject

Stop the scanner thread. If the scanner is already stopped, this method will return without taking any action.



52
53
54
55
56
57
58
59
60
61
# File 'lib/directory_watcher/scanner.rb', line 52

def stop
  return unless running?

  @stop = true
  @thread.wakeup if @thread.status == 'sleep'
  @thread.join
  self
ensure
  @thread = nil
end