Class: Rerun::Watcher

Inherits:
Object
  • Object
show all
Defined in:
lib/rerun/watcher.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}, &client_callback) ⇒ Watcher

Create a file system watcher. Start it by calling #start.

Parameters:

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

    the directory to watch (default “.”)

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

    the glob pattern to search under the watched directory (default “*/”)

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

    the priority of the watcher thread (default 0)



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rerun/watcher.rb', line 23

def initialize(options = {}, &client_callback)
  @client_callback = client_callback

  options = {
      :directory => ".",
      :pattern => "**/*",
      :priority => 0,
  }.merge(options)

  @pattern = options[:pattern]
  @directory = options[:directory]
  @directory.chomp!("/")
  unless FileTest.exists?(@directory) && FileTest.readable?(@directory)
    raise InvalidDirectoryError, "Directory '#{@directory}' either doesnt exist or isnt readable"
  end
  @priority = options[:priority]
  @thread = nil
end

Instance Attribute Details

#directoryObject (readonly)

Returns the value of attribute directory.



15
16
17
# File 'lib/rerun/watcher.rb', line 15

def directory
  @directory
end

#patternObject (readonly)

Returns the value of attribute pattern.



15
16
17
# File 'lib/rerun/watcher.rb', line 15

def pattern
  @pattern
end

#priorityObject (readonly)

Returns the value of attribute priority.



15
16
17
# File 'lib/rerun/watcher.rb', line 15

def priority
  @priority
end

Instance Method Details

#adapterObject



64
65
66
67
68
69
# File 'lib/rerun/watcher.rb', line 64

def adapter
  timeout(4) do
    sleep 1 until adapter = @listener.instance_variable_get(:@adapter)
    adapter
  end
end

#joinObject

wait for the file watcher to finish



83
84
85
86
87
# File 'lib/rerun/watcher.rb', line 83

def join
  @thread.join if @thread
rescue Interrupt => e
  # don't care
end

#startObject



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rerun/watcher.rb', line 42

def start
  if @thread then
    raise RuntimeError, "already started"
  end

  @thread = Thread.new do
    # todo: multiple dirs

    regexp = Glob.new(@pattern).to_regexp
    @listener = Listen::Listener.new(@directory, :filter => regexp) do |modified, added, removed|
      @client_callback.call(:modified => modified, :added => added, :removed => removed)
    end
    @listener.start
  end

  @thread.priority = @priority

  sleep 0.1 until @listener

  at_exit { stop } # try really hard to clean up after ourselves
end

#stopObject

kill the file watcher thread



72
73
74
75
76
77
78
79
80
# File 'lib/rerun/watcher.rb', line 72

def stop
  @thread.wakeup rescue ThreadError
  begin
    @listener.stop
  rescue Exception => e
    puts "#{e.class}: #{e.message} stopping listener"
  end
  @thread.kill rescue ThreadError
end