module Eye::Controller::Load

Constants

BT_REGX

regexp for clean backtrace to show for user

Public Instance Methods

check(filename) click to toggle source
# File lib/eye/controller/load.rb, line 3
def check(filename)
  { filename => catch_load_error(filename) { parse_config(filename).to_h } }
end
explain(filename) click to toggle source
# File lib/eye/controller/load.rb, line 7
def explain(filename)
  { filename => catch_load_error(filename) { parse_config(filename).to_h } }
end
load(*args) click to toggle source
# File lib/eye/controller/load.rb, line 11
def load(*args)
  h = args.extract_options!
  obj_strs = args.flatten
  info "=> loading: #{obj_strs}"

  res = Hash.new

  globbing(*obj_strs).each do |filename|
    res[filename] = catch_load_error(filename) do
      cfg = parse_config(filename)
      load_config(filename, cfg)
      nil
    end
  end

  set_proc_line

  info "<= loading: #{obj_strs}, in: <#{$$}>"

  res
end

Private Instance Methods

catch_load_error(filename = nil) { || ... } click to toggle source
# File lib/eye/controller/load.rb, line 38
def catch_load_error(filename = nil, &block)
  { :error => false, :config => yield }

rescue Eye::Dsl::Error, Exception, NoMethodError => ex
  raise if ex.class.to_s.include?('RR') # skip RR exceptions

  error "loading: config error <#{filename}>: #{ex.message}"

  # filter backtrace for user output
  bt = (ex.backtrace || [])
  bt = bt.reject{|line| line.to_s =~ BT_REGX } unless ENV['EYE_FULL_BACKTRACE']
  error bt.join("\n")

  res = { :error => true, :message => ex.message }
  res.merge!(:backtrace => bt) if bt.present?
  res
end
create_objects(apps_config, changed_apps = []) click to toggle source

create objects as diff, from configs

# File lib/eye/controller/load.rb, line 113
def create_objects(apps_config, changed_apps = [])
  debug 'creating objects'

  apps_config.each do |app_name, app_cfg|
    update_or_create_application(app_name, app_cfg.clone) if changed_apps.include?(app_name)
  end

  # sorting applications
  @applications.sort_by!(&:name)
end
globbing(*obj_strs) click to toggle source
# File lib/eye/controller/load.rb, line 56
def globbing(*obj_strs)
  res = []
  return res if obj_strs.empty?

  obj_strs.each do |filename|
    mask = if File.directory?(filename)
      File.join filename, '{*.eye}'
    else
      filename
    end

    debug "loading: globbing mask #{mask}"

    sub = []
    Dir[mask].each do |config_path|
      sub << config_path
    end
    sub = [mask] if sub.empty?

    res += sub
  end

  res
end
load_config(filename, config) click to toggle source

!!! exclusive operation

# File lib/eye/controller/load.rb, line 92
def load_config(filename, config)
  info "loading: #{filename}"
  new_cfg = @current_config.merge(config)
  new_cfg.validate!

  load_options(new_cfg.settings)
  create_objects(new_cfg.applications, config.application_names)
  @current_config = new_cfg
end
load_options(opts) click to toggle source

load global config options

# File lib/eye/controller/load.rb, line 103
def load_options(opts)
  return if opts.blank?

  opts.each do |key, value|
    method = "set_opt_#{key}"
    send(method, value) if value && respond_to?(method)
  end
end
parse_config(filename) click to toggle source

return: result, config

# File lib/eye/controller/load.rb, line 82
def parse_config(filename)
  debug "parsing: #{filename}"

  cfg = Eye::Dsl.parse(nil, filename)
  @current_config.merge(cfg).validate!(false) # just validate summary config here
  Eye.parsed_config = nil # remove link on config, for better gc
  cfg
end
update_or_create_application(app_name, app_config) click to toggle source
# File lib/eye/controller/load.rb, line 124
def update_or_create_application(app_name, app_config)
  @old_groups = {}
  @old_processes = {}

  app = @applications.detect { |c| c.name == app_name }

  if app
    app.groups.each do |group|
      @old_groups[group.name] = group
      group.processes.each do |proc|
        @old_processes[group.name + ":" + proc.name] = proc
      end
    end

    @applications.delete(app)

    debug "updating app: #{app_name}"
  else
    debug "creating app: #{app_name}"
  end

  app = Eye::Application.new(app_name, app_config)
  @applications << app
  @added_groups, @added_processes = [], []

  new_groups = app_config.delete(:groups) || {}
  new_groups.each do |group_name, group_cfg|
    group = update_or_create_group(group_name, group_cfg.clone)
    app.add_group(group)
    group.resort_processes
  end

  # now, need to clear @old_groups, and @old_processes
  @old_groups.each{|_, group| group.clear; group.send_command(:delete) }
  @old_processes.each{|_, process| process.send_command(:delete) if process.alive? }

  # schedule monitoring for new groups, processes
  added_fully_groups = []
  @added_groups.each do |group|
    if group.processes.size > 0 && (group.processes.pure - @added_processes).size == 0
      added_fully_groups << group
      @added_processes -= group.processes.pure
    end
  end

  added_fully_groups.each{|group| group.send_command :monitor }
  @added_processes.each{|process| process.send_command :monitor }

  # remove links to prevent memory leaks
  @old_groups = nil
  @old_processes = nil
  @added_groups = nil
  @added_processes = nil

  app.resort_groups

  app
end
update_or_create_group(group_name, group_config) click to toggle source
# File lib/eye/controller/load.rb, line 183
def update_or_create_group(group_name, group_config)
  group = if @old_groups[group_name]
    debug "updating group: #{group_name}"
    group = @old_groups.delete(group_name)
    group.schedule :update_config, group_config, Eye::Reason::User.new(:'load config')
    group.clear
    group
  else
    debug "creating group: #{group_name}"
    gr = Eye::Group.new(group_name, group_config)
    @added_groups << gr
    gr
  end

  processes = group_config.delete(:processes) || {}
  processes.each do |process_name, process_cfg|
    process = update_or_create_process(process_name, process_cfg.clone)
    group.add_process(process)
  end

  group
end
update_or_create_process(process_name, process_cfg) click to toggle source
# File lib/eye/controller/load.rb, line 206
def update_or_create_process(process_name, process_cfg)
  postfix = ":" + process_name
  name = process_cfg[:group] + postfix
  key = @old_processes[name] ? name : @old_processes.keys.detect { |n| n.end_with?(postfix) }

  if @old_processes[key]
    debug "updating process: #{name}"
    process = @old_processes.delete(key)
    process.schedule :update_config, process_cfg, Eye::Reason::User.new(:'load config')
    process
  else
    debug "creating process: #{name}"
    process = Eye::Process.new(process_cfg)
    @added_processes << process
    process
  end
end