note description : "aranea_profiling application root class" date : "$Date$" revision : "$Revision$" class APPLICATION inherit PROFILING_CONSTANTS DT_SHARED_SYSTEM_CLOCK KL_SHARED_EXCEPTIONS PROFILING_UTILS create make feature {NONE} -- Initialization make -- Run application. local l_sender_thread: WORKER_THREAD l_receiver_thread: WORKER_THREAD do parse_command_line if start_receiver_flag.was_found then create l_receiver_thread.make (agent start_receiver) l_receiver_thread.launch end if start_sender_flag.was_found then -- create l_sender_thread.make (agent start_sender) -- l_sender_thread.launch create sender.make_test_node end -- wait a bit until the nodes have started (there is no other way to do this) -- (create {EXECUTION_ENVIRONMENT}).sleep (5000000000) -- print ("waiting for nodes...") -- from -- until -- nodes_ready -- loop -- (create {EXECUTION_ENVIRONMENT}).sleep (5000000000) -- print("nodes not ready yet, going to sleep again") -- end print ("system ready%N") -- send_messages end nodes_ready: BOOLEAN -- do Result := (start_receiver_flag.was_found implies receiver /= Void) and (start_sender_flag.was_found implies sender /= Void) end parse_command_line -- parse the passed options local parser: AP_PARSER do create parser.make parser.set_application_description ("This is the aranea profiling application used to measure the performance of the transport bus") create start_sender_flag.make ('s', "start_sender") start_sender_flag.set_description ("Starts the sender node and performs analysis afterwards") parser.options.force_last (start_sender_flag) create start_receiver_flag.make ('r', "start_receiver") start_receiver_flag.set_description ("Starts the receiver node") parser.options.force_last (start_receiver_flag) create repetitions_option.make_with_long_form ("repetitions") repetitions_option.set_description ("The nr of messages to send") repetitions_option.set_parameter_description ("NR_OF_REPETITIONS") parser.options.force_last (repetitions_option) parser.parse_arguments end start_sender -- start the node asynchronously as `make' is blocking! do create sender.make_test_node end start_receiver -- start the node asynchronously as `make' is blocking! do create receiver.make_test_node end feature {NONE} -- Implementation remaining_messages: INTEGER -- the nr of remaining messages to send timestamps: DS_ARRAYED_LIST [INTEGER] -- timestamps of the sender send_messages -- start sending messages local l_repetitions: INTEGER do if repetitions_option.was_found then l_repetitions := repetitions_option.parameter else l_repetitions := repetitions_default end remaining_messages := l_repetitions print("sending " + l_repetitions.out + " messges...") send_message end send_message -- sends a single message local l_msg: A_GENERAL_STRING_MESSAGE l_milis: INTEGER do create l_msg.make_from_string ("TEST") l_msg.set_reply_handler (agent handle_reply) l_milis := system_clock.time_now.millisecond_count sender.send_message (l_msg, receiver.aranea_prefix + echo_node_name) end request_results -- request the measurements from the receiver local l_msg: A_GENERAL_STRING_MESSAGE do create l_msg.make_from_string (result_msg_prefix) l_msg.set_reply_handler (agent handle_results) sender.send_message (l_msg, receiver.aranea_prefix + echo_node_name) end handle_reply (a_msg: A_MESSAGE) -- Handle the reply msg do print("received reply") -- measure time and book keeping remaining_messages := remaining_messages - 1 if remaining_messages > 0 then -- send another regular test message send_message else -- request measurements from the receiver node request_results end end handle_results (a_msg: A_GENERAL_STRING_MESSAGE) -- results have been received, perform the analysis -- the receiver sends back a list of timestamps local l_list: LIST [STRING] l_results: DS_ARRAYED_LIST [INTEGER] l_timestamp: INTEGER do -- convert the response l_list := a_msg.string.value.split (' ') create l_results.make (l_list.count) from l_list.start until l_list.off loop l_timestamp := l_list.item_for_iteration.to_integer l_results.force_last (l_timestamp) l_list.forth end -- start analysis analyze (l_results) end analyze (a_receiver_timestamps: DS_ARRAYED_LIST [INTEGER]) -- Analyze the measurements local l_request_times: DS_ARRAYED_LIST [INTEGER] -- transmission times for the request (from sender to receiver) l_response_times: DS_ARRAYED_LIST [INTEGER] -- transmission times for the response (from receiver to sender) i,delta: INTEGER do create l_request_times.make_default create l_response_times.make_default if timestamps.count /= a_receiver_timestamps.count then -- something is not right here... print ("cannot compute analysis: Nr. of timestamps from sender and receiver do not match!") Exceptions.die (-1) end -- compute all the transmission times from i := 1 until i > timestamps.count loop if (i \\ 2 = 0) then -- receiver -> sender delta := timestamps.item (i) - a_receiver_timestamps.item (i) l_response_times.force_last (delta) else -- sender -> receiver delta := a_receiver_timestamps.item (i) - timestamps.item (i) l_request_times.force_last (delta) end i := i + 1 end -- print report print("Request transmission times: ") print(l_request_times.to_array) print("%N") print("mean: " + compute_mean (l_request_times.to_array).out) print("%N%N") print("Response transmission times: ") print(l_response_times.to_array) print("%N") print("mean: " + compute_mean (l_response_times.to_array).out) print("%N%N") end feature {NONE} -- Nodes sender: SENDER_NODE receiver: RECEIVER_NODE feature -- command line parsing start_sender_flag: AP_FLAG start_receiver_flag: AP_FLAG repetitions_option: AP_INTEGER_OPTION -- the nr. of repetitions end