Class: Conveyor::Foreman

Inherits:
Object
  • Object
show all
Includes:
Output, Singleton
Defined in:
lib/conveyor/foreman.rb

Overview

Handle the incoming watch requests and assign the workers

Constant Summary

Constants included from Output

Output::MSGLVLS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Output

#announce, #debug, #error, #info, #loglvl, #notify, #output, #say, #send_notifications, #should_log?, #warning

Constructor Details

#initializeForeman

Returns a new instance of Foreman.



9
10
11
12
13
14
15
# File 'lib/conveyor/foreman.rb', line 9

def initialize
  loglvl(:debug)
  read_configs

  @listeners = {}
  @belts = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, value = nil) ⇒ Object



170
171
172
# File 'lib/conveyor/foreman.rb', line 170

def method_missing(method, value = nil)
  return method.to_s
end

Instance Attribute Details

#channelObject

Returns the value of attribute channel.



7
8
9
# File 'lib/conveyor/foreman.rb', line 7

def channel
  @channel
end

#configObject

Returns the value of attribute config.



7
8
9
# File 'lib/conveyor/foreman.rb', line 7

def config
  @config
end

#workersObject

Returns the value of attribute workers.



7
8
9
# File 'lib/conveyor/foreman.rb', line 7

def workers
  @workers
end

Instance Method Details

#anyObject



113
114
115
# File 'lib/conveyor/foreman.rb', line 113

def any
  '*'
end

#checkObject



142
143
144
145
146
147
148
# File 'lib/conveyor/foreman.rb', line 142

def check
  @belts.each do |dir, b|
    EM.defer do
      b.check
    end
  end
end

#extension(glob) ⇒ Object



109
110
111
# File 'lib/conveyor/foreman.rb', line 109

def extension(glob)
  /\.#{glob}$/
end

#file(glob) ⇒ Object



105
106
107
# File 'lib/conveyor/foreman.rb', line 105

def file(glob)
  /#{glob}$/
end

#load!Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/conveyor/foreman.rb', line 150

def load!
  stop!

  info "Loading workers from #{@config[:worker_defs]}"
  FileUtils.mkdir_p(@config[:worker_defs])

  Dir.glob(File.join(@config[:worker_defs], '*.worker')) do |file|
    begin
      @current_worker = File.expand_path(file)
      instance_eval File.read(@current_worker)
    rescue => e
      error [
        "Error loading #{@current_worker}, skipping",
        e.message,
        e.backtrace
      ].flatten
    end
  end
end

#logfileObject



17
18
19
# File 'lib/conveyor/foreman.rb', line 17

def logfile
  @config[:logfile]
end

#match(*args, &block) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/conveyor/foreman.rb', line 77

def match(*args, &block)
  opts = args.extract_options!
  debug "Filters: #{args.inspect}"

  debug "Force polling" if @listener_opts[:force_polling]
  listener_opts = { latency: @listener_opts[:latency] || 0.5, force_polling: @listener_opts[:force_polling] }

  b = @belts[@listener_dir] = Belt.new(@listener_dir, @current_worker)
  callback = lambda do |modified, added, removed|
    begin
      files = modified + added
      b.touch(files) unless files.empty?
    rescue => e
      puts "Error: " + e.message
      puts e.backtrace
    end
  end

  listener = Listen.to(@listener_dir, listener_opts, &callback)
  listener.ignore(opts[:ignore]) if @listener_opts[:ignore]
  listener.only(*args)

  @listeners[@listener_dir] = listener
rescue => e
  error "ERROR: #{e.message}"
  error e.backtrace
end

#nameObject



21
22
23
# File 'lib/conveyor/foreman.rb', line 21

def name
  'Foreman'
end

#notify_listObject



117
118
119
120
121
# File 'lib/conveyor/foreman.rb', line 117

def notify_list
  @notify_list.flatten!
  @notify_list.uniq!
  @notify_list
end

#output_statusObject



137
138
139
140
# File 'lib/conveyor/foreman.rb', line 137

def output_status
  status = @belts.collect { |dir, b| "#{b.name}: #{b.count}" }
  print "\r#{status.join(', ')}"
end

#read_configsObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/conveyor/foreman.rb', line 29

def read_configs
  @config = {
    "worker_defs" => File.expand_path('.workers', Dir.pwd),
    "logfile" => File.expand_path('log/conveyor.log', Dir.pwd),
    "threadpool" => 5,
    "websocket" => {
      "disabled" => false,
      "host" => "0.0.0.0",
      "port" => 9876
    }
  }

  @config_file = '.conveyor'
  if File.exists? @config_file
    @config.merge! YAML.load(File.open(@config_file))
  elsif File.exists?('~/.conveyor')
    @config_file = '~/.conveyor'
    @config.merge! YAML.load(File.open(@config_file))
  else
    write_config(@config)
  end

  # New version of conveyor update config file with new params
  if !@config['version'] || @config['version'] != Conveyor::VERSION
    @config['version'] = Conveyor::VERSION
    write_config(@config)
  end

  @config.symbolize_keys!
  @config[:websocket].symbolize_keys!
end

#startObject



129
130
131
132
133
134
135
# File 'lib/conveyor/foreman.rb', line 129

def start
  load!
  @listeners.each do |k, listener|
    info "Watching #{k}"
    listener.start
  end
end

#stop!Object



123
124
125
126
127
# File 'lib/conveyor/foreman.rb', line 123

def stop!
  @listeners.each { |dir,l| info "Stopping #{dir} listener"; l.stop }
  @listeners = {}
  @notify_list = []
end

#watch(*args, &block) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/conveyor/foreman.rb', line 65

def watch(*args, &block)
  @listener_opts = args.extract_options!
  @listener_dir = File.expand_path(args.first)
  raise "Directory #{@listener_dir} not found" unless File.directory? @listener_dir

  @listener_opts[:latency] ||= 1
  # Set a large latency if we force polling, prevents high cpu usage
  @listener_opts[:latency] = 1 if @listener_opts[:latency] < 1 and @listener_opts[:force_polling]

  yield
end

#write_config(config) ⇒ Object



61
62
63
# File 'lib/conveyor/foreman.rb', line 61

def write_config(config)
  File.open(@config_file, 'w') { |fp| fp << config.to_yaml }
end