class LoadNode
Attributes
duration_millis[R]
node_id[R]
schedule[R]
target_code[RW]
target_server[RW]
Public Class Methods
instance()
click to toggle source
# File lib/load/load_node.rb, line 16 def self.instance return @@load_node_instance end
new(run_id, server_address, node_code = nil)
click to toggle source
# File lib/load/load_node.rb, line 20 def initialize(run_id, server_address, node_code = nil) if (@@load_node_instance != nil) raise "LoadNode instance initialized a second time" end @target_code = target_code @test_index = 1 @messenger = nil @@load_node_instance = self @factory = TestFactory.new if (server_address == nil) # Perf tests don't require server else begin puts "Registering node" @run_id = run_id @child_pids = [] @messenger = HttpReport.new(server_address) node_info = @messenger.node_register({run_id: @run_id, address: "#{Socket.gethostname}", code: node_code}) if (node_info['configuration'] == nil) puts "Error starting node. Did run already complete?" else @configuration = eval(node_info['configuration']) @node_id = node_info["id"].to_i @node_code = node_info["code"] @target_code = node_info["target_server"] @target_server = @configuration[:servers][@target_code.to_sym] puts "Node registered: #{@node_id} Code: #{@node_code} Target server: #{@target_server}" @schedule = @messenger.node_schedule({node_id: @node_id}) @load_tests = create_node_tests(@node_id, @schedule) @duration_millis = node_info["duration"] @messenger.node_ready({node_id: @node_id}) wait_for_node_start_ok launch_node_tests wait_for_finish @messenger.node_finished({node_id: @node_id}) end rescue Interrupt puts "NODE (#{@node_id}) - Interrupt signal received, quitting. [#{self.class}]" rescue Exception => exc puts "Exception in node: #{exc.message} \n" + exc.backtrace.join("\n") ensure kill_child_processes end #exit 0 end end
Public Instance Methods
create_node_tests(node_id, node_schedule)
click to toggle source
# File lib/load/load_node.rb, line 132 def create_node_tests(node_id, node_schedule) wasp_id = 1 load_tests = [] puts "Node Schedule:" node_schedule.each do |test_schedule| test_name = test_schedule["test_name"] events = test_schedule["events"] sched_text = "Test: #{test_name} Events: " events.each do |event| sched_text += "#{event['action'].capitalize} at #{event['time']} sec " end test_config = find_config_for_test(test_name) test = @factory.create_test(test_name, @target_code, test_config) test.index = @test_index @test_index += 1 load_test = LoadTest.new(self, @run_id, node_id, wasp_id, test, events, @messenger) load_tests << load_test wasp_id += 1 end node_monitors = @messenger.node_monitors( {node_id: @node_id} ) node_monitors.each do |monitor_config| type = monitor_config["type"] name = monitor_config["name"] duration = monitor_config["duration"].to_i / 1000 if (name == nil) name = "#{type.capitalize} Monitor" end if (type == "network") puts "Config: #{monitor_config}" address = monitor_config["address"] monitor = NetworkMonitor.new(address) elsif (type == "cpu") monitor = CpuMonitor.new() elsif (type == "file.io") monitor = FileIoMonitor.new() elsif (type == "ram") monitor = RamMonitor.new() else raise "Do no know how to handle monitor type: #{type} Name: #{name}" end events = [{"time" => "0", "action" => "run"}, {"time" => "#{duration}", "action" => "pause"}] load_test = LoadTest.new(self, @run_id, node_id, wasp_id, monitor, events, @messenger) load_tests << load_test wasp_id += 1 end return load_tests end
find_config_for_test(test_name)
click to toggle source
# File lib/load/load_node.rb, line 186 def find_config_for_test(test_name) test_configs = @configuration[:tests] test_configs.each do |test_config| if (test_config[:test] == test_name) return test_config end end end
kill_child_processes()
click to toggle source
# File lib/load/load_node.rb, line 196 def kill_child_processes # puts "==================================================================================" # puts "Node Finished: #{@node_id}" # puts " Killing child PID's: #{@child_pids}" # puts "==================================================================================" # trap("INT") do # exit # end Process.kill('INT', -Process.getpgrp) # # @child_pids.each do |pid| # begin # puts "Killing: #{pid}" # Process.kill("INT", pid) # rescue Exception => e # puts "Exception killing pid #{pid}. #{e.message}" # end # end end
launch_node_tests()
click to toggle source
# File lib/load/load_node.rb, line 78 def launch_node_tests @load_tests.each do |test| pid = fork { test.run } @child_pids << pid write_pid_to_file(pid) end end
report_block_result(test_code, runner_id, time_ellapsed, benchmark_time, result)
click to toggle source
# File lib/load/load_node.rb, line 67 def report_block_result(test_code, runner_id, time_ellapsed, benchmark_time, result) @messenger.report_result(@run_id, @node_id, test_code, runner_id, time_ellapsed, benchmark_time, result) end
wait_for_finish()
click to toggle source
# File lib/load/load_node.rb, line 104 def wait_for_finish @start_time = Time.now.to_i quit = false while !quit sleep 10 ellapsed_time = Time.now.to_i - @start_time if (ellapsed_time > (@duration_millis / 1000)) quit = true puts "Node duration reached: #{@duration_millis} seconds. Node quitting" else #puts "Node duration (#{ellapsed_time} secs) NOT reached: #{@duration_millis/1000} seconds." end @messenger.node_schedule({node_id: @node_id}) status = @messenger.status_for_test(@run_id, nil) if (status['run_status'] == "killed") puts "XXXXX RUN HAS BEEN KILLED - KILLING NODE: #{@wasp_id} XXXXXXX" quit = true elsif (status['run_status'] == "finished") puts "XXXXX RUN IS FINISHED - KILLING NODE: #{@wasp_id} XXXXXXX" quit = true end end puts "Node finished. ##{@node_code}" end
wait_for_node_start_ok()
click to toggle source
# File lib/load/load_node.rb, line 89 def wait_for_node_start_ok ok_to_start = false last_message_at = 0 while (!ok_to_start) ok_to_start = @messenger.node_start?({node_id: @node_id}) sleep 0.2 if (Time.new.to_i - last_message_at > 5) puts "Node waiting for other nodes to start (#{@node_code})" last_message_at = Time.new.to_i end end puts "All Nodes Launched. Node (#{@node_code}) can start now " end
write_pid_to_file(pid)
click to toggle source
# File lib/load/load_node.rb, line 72 def write_pid_to_file(pid) open('node_pids_#{@node_id}.pid', 'a') { |f| f.puts "#{pid}\n" } end