class MiGA::Lair
Lair of MiGA Daemons handling job submissions
#
def check_directories
#
def check_directories each_project do |project| d = project_daemon(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
def daemon_first_loop
#
def daemon_first_loop say '-----------------------------------' say '%s launched' % daemon_name say '-----------------------------------' say 'Configuration options:' say options.to_s end
def daemon_loop
#
def daemon_loop check_directories return false if options[:dry] sleep(options[:latency]) true end
def daemon_name
#
def daemon_name "MiGA:#{options[:name]}" end
def each_daemon(include_self = true)
Perform block for each daemon, including the chief daemon
#
def each_daemon(include_self = true) yield(self) if include_self each_project { |project| yield(project_daemon(project)) } end
def each_project(dir = path)
Searches for MiGA projects recursively in all
passing the absolute path of the project to the block.
Perform block for each project in the +dir+ directory,
#
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) unless options[:exclude].include?(project.name) elsif Dir.exist? f each_project(f) { |p| yield(p) } end end end
def initialize(path, opts = {})
them
- dry: Only report when daemons would be launched, but don't actually launch
by default: true
project is to be trusted to determine changes in the project,
- trust_timestamp: boolean indicating if the +modified+ timestamp of the
- name: A name for the chief daemon process, by default: basename of +path+
inactive (when all tasks are complete), by default: false
- keep_inactive: boolean indicating if daemons should stay alive even when
by default: 30
- wait_for: time to wait for a daemon to report being alive in seconds,
- latency: time to wait between iterations in seconds, by default: 120
- json: json definition for all children daemons, by default: nil
to wake the chief daemon. Supported options include:
Initialize an inactive daemon for the directory at +path+. See #daemon
#
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, exclude: [] }.each { |k, v| @options[k] = v if @options[k].nil? } end
def launch_daemon(project)
Launch daemon for the MiGA::Project +project+ and returns the corresponding
#
def launch_daemon(project) say "Launching daemon: #{project.path}" daemon = project_daemon(project) daemon.runopts(:shutdown_when_done, true) unless options[:keep_inactive] unless options[:dry] daemon.start sleep(1) # <- to make sure the daemon started up (it takes about 0.1 secs) end daemon end
def project_daemon(project)
#
def project_daemon(project) MiGA::Daemon.new(project, options[:json]) end
def terminate_daemon(daemon)
Send termination message to +daemon+, an object implementing
#
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
def terminate_daemons
#
def terminate_daemons terminate_daemon(self) each_project do |project| terminate_daemon(MiGA::Daemon.new(project)) end end