public void BenchmarkPing(int reps) {
List<int> mu_sec_pings = new List<int>();
Random my_r = new Random();
ArrayList nodes = null;
lock(_sync) {
//Make a copy
nodes = new ArrayList(_node_list);
}
Stack<Action> pings = new Stack<Action>();
for(int i = 0; i < reps; i++) {
int idx0 = my_r.Next(0, nodes.Count);
int idx1 = my_r.Next(0, nodes.Count);
Node n0 = (Node)nodes[idx0];
Node n1 = (Node)nodes[idx1];
Action ping = delegate() {
RpcManager pinger = n0.Rpc;
Channel results = new Channel(1);
results.CloseEvent += delegate(object q, EventArgs a) {
try {
object result = results.Dequeue();
RpcResult r = (RpcResult)result;
IDictionary data = (IDictionary)r.Result;
int rtt = (int)data["musec"];
//Console.WriteLine("target: {0}, rtt: {1}", data["target"], data["musec"]);
mu_sec_pings.Add(rtt);
}
catch(Exception x) {
Console.WriteLine("target: {0}, Exception: {1}", n1.Address, x);
}
if( pings.Count > 0 ) {
var next = pings.Pop();
next();
}
else {
double ave_rtt = 0;
foreach(int s in mu_sec_pings) {
ave_rtt += (double)s;
}
ave_rtt /= mu_sec_pings.Count;
double var = 0;
foreach(int s in mu_sec_pings) {
var += (ave_rtt - (double)s) * (ave_rtt - (double)s);
}
var /= mu_sec_pings.Count;
var stdev = Math.Sqrt(var);
mu_sec_pings.Sort();
var median = mu_sec_pings[ mu_sec_pings.Count / 2];
Console.WriteLine("Average: {0} Median: {1} Stdev: {2} Samples: {3} Reps: {4}",
ave_rtt, median, stdev, mu_sec_pings.Count, reps);
}
};
try {
pinger.Invoke(n0, results, "trace.GetRttTo", n1.Address.ToString());
}
catch(Exception x) {
Console.WriteLine("Exception: {0}", x);
if( pings.Count > 0 ) {
var next = pings.Pop();
next();
}
else {
double ave_rtt = 0;
foreach(int s in mu_sec_pings) {
ave_rtt += (double)s;
}
ave_rtt /= mu_sec_pings.Count;
double var = 0;
foreach(int s in mu_sec_pings) {
var += (ave_rtt - (double)s) * (ave_rtt - (double)s);
}
var /= mu_sec_pings.Count;
var stdev = Math.Sqrt(var);
mu_sec_pings.Sort();
var median = mu_sec_pings[ mu_sec_pings.Count / 2];
Console.WriteLine("Average: {0} Median: {1} Stdev: {2} Samples: {3} Reps: {4}",
ave_rtt, median, stdev, mu_sec_pings.Count, reps);
}
}
};
pings.Push(ping);
}
//Now pop off the first one and go:
var first = pings.Pop();
first();
}
static void Main(string[] args) { RandomNumberGenerator rng = new RNGCryptoServiceProvider(); //Initialize hosts Console.WriteLine("\n\n---------------------------------------\n\n"); int port = 20287; int net_size = 3; string net_type = "function"; if (args.Length > 0) { net_size = Int32.Parse(args[0]); } if (args.Length > 1) { net_type = args[1]; } int ms_sleep = 0; if (args.Length > 2) { ms_sleep = Int32.Parse(args[2]); } bool wait_after_connect = true; if (args.Length > 3) { ///@todo we really need better option parsing here wait_after_connect = false; } ArrayList node_list = new ArrayList(); Hashtable add_to_node = new Hashtable(); PathELManager pem = null; for (int loop = 0; loop < net_size; loop++) { //create and initialize new host //create one new node for each host AHAddress tmp_add = new AHAddress(rng); Node tmp_node = new StructuredNode(tmp_add, "bstland"); //Node tmp_node = new HybridNode(tmp_add, "bstland"); node_list.Add(tmp_node); add_to_node[tmp_add] = tmp_node; //long small_add = 2*(loop+1); //Node tmp_node = new StructuredNode(new AHAddress( new BigInteger(small_add)) ); PType path_p = PType.Protocol.Pathing; switch (net_type) { case "tcp": tmp_node.AddEdgeListener(new TcpEdgeListener(port + loop)); break; case "udp": tmp_node.AddEdgeListener(new UdpEdgeListener(port + loop)); break; case "function": tmp_node.AddEdgeListener(new FunctionEdgeListener(port + loop)); break; case "path": if (pem == null) { EdgeListener el = new UdpEdgeListener(port); pem = new PathELManager(el); pem.Start(); } //Pass path messages to the pem: tmp_node.DemuxHandler.GetTypeSource(path_p).Subscribe(pem, path_p); tmp_node.AddEdgeListener(pem.CreatePath((port + loop).ToString())); Console.WriteLine(port + loop); break; case "single_path": EdgeListener myel = new UdpEdgeListener(port + loop); //Test "default" path edge listener: pem = new PathELManager(myel); pem.Start(); tmp_node.DemuxHandler.GetTypeSource(path_p).Subscribe(pem, path_p); //Make the default path: tmp_node.AddEdgeListener(pem.CreateRootPath()); break; default: throw new Exception("Unknown net type: " + net_type); } //tmp_node.AddEdgeListener(new FunctionEdgeListener(port+loop)); for (int loop2 = 0; loop2 < net_size; loop2++) { if (loop == loop2) { continue; } int other_port = port + loop2; string ta_str = null; switch (net_type) { case "tcp": ta_str = "brunet.tcp://127.0.0.1:"; break; case "udp": ta_str = "brunet.udp://127.0.0.1:"; break; case "function": ta_str = "brunet.function://localhost:"; break; case "path": ta_str = String.Format("brunet.udp://127.0.0.1:{0}/", port); break; case "single_path": ta_str = "brunet.udp://127.0.0.1:"; break; default: throw new Exception("Unknown net type: " + net_type); } ta_str = ta_str + other_port.ToString(); TransportAddress this_ta = TransportAddressFactory.CreateInstance(ta_str); tmp_node.RemoteTAs.Add(this_ta); } } //This logs the changes in connection table BootStrapTester bst = new BootStrapTester(node_list); if (bst != null) { //This is just here to prevent a warning for //not using bst, which is just an observer } //Get Connected: int total_started = 0; ArrayList rnd_list = (ArrayList)node_list.Clone(); Random rnd = new Random(); for (int j = 0; j < rnd_list.Count; j++) { //Swap the j^th position with this position: int i = rnd.Next(j, rnd_list.Count); if (i != j) { object o = rnd_list[i]; rnd_list[i] = rnd_list[j]; rnd_list[j] = o; } } ArrayList c_threads = new ArrayList(); //var xrms = new Brunet.Rpc.XmlRpcManagerServer(20000); int cnt = 0; foreach (Node item in rnd_list) { Thread t = new Thread(item.Connect); c_threads.Add(t); t.Start(); //xrms.Add(item, "xm" + cnt++ + ".rem"); Console.WriteLine(item.Address.ToString() + " RemoteTAs count: " + item.RemoteTAs.Count); total_started++; Console.WriteLine("Started: " + total_started.ToString()); //Thread.Sleep(10000); Thread.Sleep(ms_sleep); //Console.ReadLine(); //foreach (TransportAddress item2 in item.RemoteTAs) // Console.WriteLine(item2); } System.Console.Out.WriteLine("Finished with BootStrapTester.Main"); string[] this_command = new string[] { "Q" }; if (wait_after_connect) { Console.WriteLine("Enter Q to stop"); this_command = Console.ReadLine().Split(' '); } while (this_command[0] != "Q") { if (this_command[0] == "D") { //Disconnect a node: int node = -1; try { node = Int32.Parse(this_command[1]); Node to_disconnect = (Node)node_list[node]; Console.WriteLine("About to Disconnect: {0}", to_disconnect.Address); to_disconnect.Disconnect(); bst.Remove(to_disconnect); } catch (Exception) { } } if (this_command[0] == "abort") { //Disconnect a node: int node = -1; try { node = Int32.Parse(this_command[1]); Node to_abort = (Node)node_list[node]; Console.WriteLine("About to Abort: {0}", to_abort.Address); to_abort.Abort(); bst.Remove(to_abort); } catch (Exception) { } } if (this_command[0] == "P") { //Pick a random pair of nodes to ping: Ping(node_list); } if (this_command[0] == "BP") { try { int reps = Int32.Parse(this_command[1]); bst.BenchmarkPing(reps); } catch (Exception x) { Console.WriteLine(x); } } if (this_command[0] == "BH") { try { int reps = Int32.Parse(this_command[1]); bst.BenchmarkHops(reps); } catch (Exception x) { Console.WriteLine(x); } } if (this_command[0] == "T") { //Pick a random pair of nodes to ping: TraceRoute(node_list); } if (wait_after_connect) { this_command = Console.ReadLine().Split(' '); } } foreach (Node n in node_list) { n.Disconnect(); } if (pem != null) { pem.Stop(); } //Block until all Connect threads finish. //foreach(Thread t in c_threads) { // t.Join(); //} }