require 'server' require 'scenario' require 'client' require 'master_web' require 'rubygems' require 'rack/handler/mongrel' Thread.abort_on_exception = true class Master include Server def initialize @new_nodes = [] end attr_reader :scenario, :scenario_name def change_scenario(scenario_name) if Scenario.index[scenario_name] @scenario_name = scenario_name @scenario = Scenario.index[scenario_name].new @scenario.run(Client.clients) end end def run run_server '0.0.0.0', 9125 do |client_socket| if Client.clients.size > 19 client_socket.send 't' => 'DIE', 'err' => 'Too many connections. Sorry!' client_socket.close else puts "+++ #{client_socket.addr} (#{client_socket.hostname}) has connected" c = Client.new(client_socket) @new_nodes << c end end end def print_state Client.clients.each do |client| msg = client.msg 't' => 'STATE' puts "#{client.addr} state: #{msg.inspect}" end end def states Client.clients.map { |client| [client, client.msg('t' => 'STATE')] } end def get_new_nodes new_nodes = clear_new_nodes new_nodes.map { |client| [client, client.msg('t' => 'STATE')] } end def clear_new_nodes new_nodes = @new_nodes @new_nodes = [] new_nodes end end if __FILE__ == $0 p Scenario.index master = Master.new master.run Thread.new { web = MasterWeb.new(master) Rack::Handler::Mongrel.run web, :Port => 8000 } loop do cmd = gets.chomp case cmd when '' exit when 'state' master.print_state when /^enable_link / c, node_addr, type, link_addr = cmd.split(/\s+/) client = Client.clients.detect { |c| c.addr == node_addr } if client c.msg 't' => 'LINKUP', 'type' => type, 'addr' => link_addr else puts "Could not find client" end when /^disable_link / c, node_addr, type, link_addr = cmd.split(/\s+/) client = Client.clients.detect { |c| c.addr == node_addr } if client c.msg 't' => 'LINKDOWN', 'type' => type, 'addr' => link_addr else puts "Could not find client" end else master.change_scenario cmd end end end