class Ignition::Manager

Constants

BUNDLES_JSON
BUNDLES_STATUS_JSON

Attributes

env[R]

Public Class Methods

new(broadcast_client) click to toggle source
Calls superclass method
# File lib/ignition/engine/manager.rb, line 12
def initialize(broadcast_client)
        #load the plugs
        super()

        @recent_logs = {}

        @registered_bundles = {}

        @process_ids = {}

        @shutdown = false

        @broadcast_client = broadcast_client

        @broadcast_client.add_message_listener(self)

        @network_daemons = {}

        env = ENV
        
        @bundles = load_bundles

        BundleHelper.prepare_bundles(@bundles)

        register_bundles

        register_signal_handlers

        start_network_ping
end

Public Instance Methods

add_process(bundle,index) click to toggle source
# File lib/ignition/engine/manager.rb, line 289
def add_process(bundle,index)
        proc = process(bundle.id)
pid =spawn_process(bundle,proc,index)  
bundle.status.add_pid(pid)
# update_bundle_running_status(b)
end
apply_scale(bundle,count) click to toggle source
# File lib/ignition/engine/manager.rb, line 261
def apply_scale(bundle,count)
        pp bundle
        puts bundle.status.scale.class
        puts "currently running #{bundle.status.scale}. Wanted #{count}"
        if (bundle.status.scale > count)
                # downscale to count. kill processes
                bundle.status.scale.downto(count+1) do |n|
                        puts "apply_scale down #{n}"
                        if n >= 1
                                remove_process(bundle,n)
                                sleep(0.1)
                        end
                end
        elsif (bundle.status.scale < count)
                # add processes
                # diff = count - bundle.status.scale
                puts "adding process."
                (bundle.status.scale+1).upto(count) do |n|
                        puts "apply_scale up #{n}" 
                        if n >= 1
                                add_process(bundle,n)
                                sleep(0.1)
                        end
                end
        end
        # update_bundle_running_status(bundle)
end
bundle(id) click to toggle source
# File lib/ignition/engine/manager.rb, line 247
def bundle(id)
        @bundles.select{ |b| b.id == id }.first
end
bundles() click to toggle source
# File lib/ignition/engine/manager.rb, line 43
def bundles
        @bundles
end
bundles_json() click to toggle source
# File lib/ignition/engine/manager.rb, line 326
def bundles_json
        begin
                FileUtils.mkdir_p File.dirname(BUNDLES_JSON)
                File.read(BUNDLES_JSON)
        rescue Exception => exc
                # puts exc.message
                # puts exc.backtrace
                "[]"
        end
end
bundles_status_json() click to toggle source
# File lib/ignition/engine/manager.rb, line 337
def bundles_status_json
        begin
                FileUtils.mkdir_p File.dirname(BUNDLES_STATUS_JSON)
                File.read(BUNDLES_STATUS_JSON)
        rescue Exception => exc
                # puts exc.message
                # puts exc.backtrace
                "[]"
        end
end
flush() click to toggle source
# File lib/ignition/engine/manager.rb, line 362
def flush
        remove_old_pids(@bundles)
        File.write(BUNDLES_JSON,JSON.pretty_generate( @bundles.map{|b| b.reject{|k| k == "status"}} ))
        File.write(BUNDLES_STATUS_JSON,JSON.pretty_generate( @bundles.map do |b| 
                        { "id" => b.id , "status" => b.status } 
        end
        ))
end
handle_hangup() click to toggle source
# File lib/ignition/engine/manager.rb, line 197
def handle_hangup
    puts "custom SIGHUP received"
    terminate_gracefully
    @shutdown = true
    sleep(1)
    # exit(1)
    # Process.kill("EXIT", 0)
end
handle_interrupt() click to toggle source
# File lib/ignition/engine/manager.rb, line 188
def handle_interrupt
    puts "custom SIGINT received"
    terminate_gracefully
    @shutdown = true
    sleep(1)
    # exit(1)
    # Process.kill("EXIT", 0)
end
handle_term_signal() click to toggle source
# File lib/ignition/engine/manager.rb, line 179
def handle_term_signal
    puts "custom SIGTERM received"
    terminate_gracefully
    @shutdown = true
    sleep(1)
    # exit(1)
    # Process.kill("EXIT", 0)
end
kill_process_and_wait(pid,signal="SIGTERM") click to toggle source
# File lib/ignition/engine/manager.rb, line 234
def kill_process_and_wait(pid,signal="SIGTERM")
      begin
       puts "killing process #{pid}"
        Process.kill signal, pid
      rescue Errno::ESRCH, Errno::EPERM
      end
      begin
       Process.wait(pid)
       puts "process finished #{pid}"
          rescue Errno::ECHILD
          end
end
load_bundle(bh) click to toggle source

end from foreman engine

# File lib/ignition/engine/manager.rb, line 84
def load_bundle(bh)
        if (!bundle(bh.id).nil?)
                raise "Bundle Exists. Unload bundle before adding."
        end

        bundle = Ignition::Bundle.new(bh)
        BundleHelper.prepare_bundle(bundle)

        @bundles << bundle
        register_bundle(bundle)
        flush
end
load_bundles() click to toggle source
# File lib/ignition/engine/manager.rb, line 348
def load_bundles
        bundles = JSON.parse(bundles_json).map { |b| Ignition::Bundle.new(b) }
        # pp @bundles

        JSON.parse(bundles_status_json).each do |bs| 
                # bundles
                b = bundles.select{ |b| b.id == bs.id }.first 
                unless b.nil?
                        b.status = Ignition::BundleStatus.new(bs.status)
                end
        end
        remove_old_pids(bundles)
end
logs(bundle_id) click to toggle source
# File lib/ignition/engine/manager.rb, line 407
def logs(bundle_id)
        # @recent_logs[bundle_id]
        proc_ids = @recent_logs.keys.select { |a| a.scan(/#{bundle_id}.\d+/).size > 0 }

        proc_ids.map { |b| @recent_logs[b].to_a }.flatten
end
name_for_bundle_index(bundle,index) click to toggle source

OVERRIDES END

# File lib/ignition/engine/manager.rb, line 208
def name_for_bundle_index(bundle,index)
        [ bundle.id, index.to_s ].compact.join(".")
end
network_daemons() click to toggle source
# File lib/ignition/engine/manager.rb, line 384
def network_daemons
        @network_daemons
end
new_message(message) click to toggle source
# File lib/ignition/engine/manager.rb, line 378
def new_message(message)
        # pp message

        @network_daemons[message.handle] = Time.now
end
output(name, data) click to toggle source
# File lib/ignition/engine/manager.rb, line 69
def output(name, data)
       log = "#{Time.now.strftime("%H:%M:%S.%L")} - #{data}"
       puts "#{name} - #{log}"

       if @recent_logs[name].nil?
               @recent_logs[name] = FixedArray.new(100)
       end
       @recent_logs[name].push(log)
end
process_count() click to toggle source

end

# File lib/ignition/engine/manager.rb, line 318
def process_count
        @process_ids.count
end
process_ids() click to toggle source
# File lib/ignition/engine/manager.rb, line 322
def process_ids
        @process_ids
end
recent_logs() click to toggle source
# File lib/ignition/engine/manager.rb, line 403
def recent_logs
        @recent_logs
end
register(name, command, options={}) click to toggle source
# File lib/ignition/engine/manager.rb, line 170
def register(name, command, options={})
       options[:env] ||= env
       options[:cwd] ||= File.dirname(command.split(" ").first)
       process = Foreman::Process.new(command, options)
       @names[process] = name
       @processes << process
       process #just return the process!
end
register_bundle(bundle) click to toggle source
# File lib/ignition/engine/manager.rb, line 54
def register_bundle(bundle)
        puts "Register bundle #{bundle.id}"

        options = {}
        options[:cwd] = bundle.cwd 
        
        proc = register(bundle.id,bundle.command,options)

        @registered_bundles[proc] = bundle
end
register_bundles() click to toggle source
# File lib/ignition/engine/manager.rb, line 47
def register_bundles
        @bundles.each do |b|
                register_bundle(b)
        end
        pp @registered_bundles
end
remove_old_pids(bundles) click to toggle source
# File lib/ignition/engine/manager.rb, line 371
def remove_old_pids(bundles)
        bundles.each do |b|
                b.status.clean_pids
        end
end
remove_process(bundle,index) click to toggle source
# File lib/ignition/engine/manager.rb, line 296
def remove_process(bundle,index)
        name = name_for_bundle_index(bundle, index)
        pid = @process_ids[name]
        unless pid.nil?
                kill_process_and_wait(pid)
                # bundle.scale.pids.reject! { |p| p == pid }
                bundle.status.remove_pid(pid)
        end
end
run(on_shutdown) click to toggle source

end

# File lib/ignition/engine/manager.rb, line 117
def run(on_shutdown)
        Thread.new {
                begin
                        spawn_processes
                    watch_for_output
                    flush
                    sleep 0.1
                    
                    while(!@shutdown)
                    # loop {
                  pid = watch_for_termination { 
                             puts "child died"
                             # terminate_gracefully
                     }
                     # puts "got pid notification #{pid}"
                                if pid.nil?
                                        sleep(1)
                                        # puts "waiting for child process"
                                end
                        end
                        puts "spawn thread complete."
                        # loop { sleep(1000) }
                        on_shutdown.call
                rescue Exception => exc
                        puts exc.message
                        puts exc.backtrace
                        terminate_gracefully
                        on_shutdown.call 
                end
        }

end
scale(name,count) click to toggle source
# File lib/ignition/engine/manager.rb, line 251
def scale(name,count)
        bundle_to_scale = bundle(name)
        
        apply_scale(bundle_to_scale,count)

        bundle_to_scale.status.scale = count

        flush
end
shutdown() click to toggle source
# File lib/ignition/engine/manager.rb, line 79
def shutdown
end
spawn_process(bundle,process,n) click to toggle source
# File lib/ignition/engine/manager.rb, line 212
  def spawn_process(bundle,process,n)
    # 1.upto(count) do |n|
  reader, writer = create_pipe
  begin
          puts "starting process"
          name = name_for_bundle_index(bundle, n)
          pid = process.run(:output => writer, :env => {
          "PORT" => port_for(process, n).to_s,
          "PS" => name
          })
          puts "started process"
          @process_ids[name] = pid
          writer.puts "started with pid #{pid}"
  rescue Errno::ENOENT
    writer.puts "unknown command: #{process.command}"
  end
  @running[pid] = [process, n]
  @readers[pid] = reader
# end
  pid
  end
spawn_processes() click to toggle source

OVERRIDES START - more like monkey patches

# File lib/ignition/engine/manager.rb, line 157
def spawn_processes
       puts "override spawn process"
    @processes.each do |process|
       b = @registered_bundles[process]
       1.upto(b.status.scale) do |n|
               pid =  spawn_process(b,process,n)  
               b.status.add_pid(pid)
       end
       # update_bundle_running_status(b)
        end
    pp @running
end
start_network_ping() click to toggle source
# File lib/ignition/engine/manager.rb, line 388
def start_network_ping
        Thread.new {
                begin
                        loop {
                                sleep(1)
                                # puts "sending ping"
                                @broadcast_client.transmit("PING")
                        }
      rescue Exception => exc
        puts exc.message
        puts exc.backtrace
      end
        }
end
startup() click to toggle source

start from foreman engine

# File lib/ignition/engine/manager.rb, line 66
def startup
end
stop() click to toggle source
# File lib/ignition/engine/manager.rb, line 150
def stop
        puts "calling stop...."
        # terminate_gracefully
        # @shutdown = true
end
unload_bundle(bh) click to toggle source
# File lib/ignition/engine/manager.rb, line 97
def unload_bundle(bh)
        if (bundle(bh.id).nil?)
                raise "Bundle #{bh.id} does NOT exist. Cannot unload."
        end

        #check for running bundles. if there are then raise error. need to be stopped first.

        # bundle = Ignition::Bundle.new(bh)
        # @bundles << bundle

        @bundles.reject! {|b| b.id == bh.id }

        # register_bundle(bundle)
        flush
end