class MiGA::Lair

Lair of MiGA Daemons handling job submissions

Attributes

daemon_home[R]

Absolute path to the directory where the projects are located

options[RW]

Options used to setup the chief daemon

path[R]

Absolute path to the directory where the projects are located

Public Class Methods

new(path, opts = {}) click to toggle source

Initialize an inactive daemon for the directory at path. See daemon to wake the chief daemon. Supported options include:

  • json: json definition for all children daemons, by default: nil

  • latency: time to wait between iterations in seconds, by default: 120

  • wait_for: time to wait for a daemon to report being alive in seconds, by default: 30

  • keep_inactive: boolean indicating if daemons should stay alive even when inactive (when all tasks are complete), by default: false

  • name: A name for the chief daemon process, by default: basename of path

  • trust_timestamp: boolean indicating if the modified timestamp of the project is to be trusted to determine changes in the project, by default: true

  • dry: Only report when daemons would be launched, but don't actually launch them

# File lib/miga/lair.rb, line 34
def initialize(path, opts = {})
  @path = File.expand_path(path)
  @options = opts
  {
    json: nil,
    latency: 30,
    wait_for: 30,
    keep_inactive: false,
    trust_timestamp: true,
    name: File.basename(@path),
    dry: false
  }.each { |k, v| @options[k] = v if @options[k].nil? }
end

Public Instance Methods

check_directories() click to toggle source

Traverse directories checking MiGA projects

# File lib/miga/lair.rb, line 129
def check_directories
  each_project do |project|
    d = MiGA::Daemon.new(project)
    next if d.active?

    l_alive = d.last_alive
    unless l_alive.nil?
      next if options[:trust_timestamp] && project.metadata.updated < l_alive
      next if l_alive > Time.now - options[:wait_for]
    end
    launch_daemon(project)
  end
end
daemon_first_loop() click to toggle source

First loop of the lair's chief daemon

# File lib/miga/lair.rb, line 60
def daemon_first_loop
  say '-----------------------------------'
  say '%s launched' % daemon_name
  say '-----------------------------------'
  say 'Configuration options:'
  say options.to_s
end
daemon_loop() click to toggle source

Run one loop step. Returns a Boolean indicating if the loop should continue.

# File lib/miga/lair.rb, line 70
def daemon_loop
  check_directories
  return false if options[:dry]

  sleep(options[:latency])
  true
end
daemon_name() click to toggle source

Name of the lair's chief daemon

# File lib/miga/lair.rb, line 54
def daemon_name
  "MiGA:#{options[:name]}"
end
each_daemon(include_self = true) { |self| ... } click to toggle source

Perform block for each daemon, including the chief daemon if include_self.

# File lib/miga/lair.rb, line 122
def each_daemon(include_self = true)
  yield(self) if include_self
  each_project { |project| yield(MiGA::Daemon.new(project)) }
end
each_project(dir = path) { |project| ... } click to toggle source

Perform block for each project in the dir directory, passing the absolute path of the project to the block. Searches for MiGA projects recursively in all subdirectories that are not MiGA projects.

# File lib/miga/lair.rb, line 103
def each_project(dir = path)
  Dir.entries(dir).each do |f|
    next if %w[. ..].include?(f) # Ruby <= 2.3 doesn't have Dir.children

    f = File.join(dir, f)
    if MiGA::Project.exist? f
      project = MiGA::Project.load(f)
      raise "Cannot load project: #{f}" if project.nil?

      yield(project)
    elsif Dir.exist? f
      each_project(f) { |project| yield(project) }
    end
  end
end
launch_daemon(project) click to toggle source

Launch daemon for the MiGA::Project project

# File lib/miga/lair.rb, line 145
def launch_daemon(project)
  say "Launching daemon: #{project.path}"
  d = MiGA::Daemon.new(project, options[:json])
  d.runopts(:shutdown_when_done, true) unless options[:keep_inactive]
  unless options[:dry]
    d.start
    sleep(1) # <- to make sure the daemon started up (it takes about 0.1 secs)
  end
end
terminate_daemon(daemon) click to toggle source

Send termination message to daemon, an object implementing +MiGA::Common::WithDaemon+

# File lib/miga/lair.rb, line 90
def terminate_daemon(daemon)
  say "Probing #{daemon.class} #{daemon.daemon_home}"
  if daemon.active?
    say 'Sending termination message'
    FileUtils.touch(daemon.terminate_file)
  end
end
terminate_daemons() click to toggle source

Terminate all daemons in the lair (including the chief daemon)

# File lib/miga/lair.rb, line 80
def terminate_daemons
  terminate_daemon(self)
  each_project do |project|
    terminate_daemon(MiGA::Daemon.new(project))
  end
end