/** * Sends a StatusMessage request (local node) to the nearest right and * left neighbors (in the local node's ConnectionTable) of the new Connection. */ protected void UpdateNeighborStatus(object contab, EventArgs args) { ConnectionEventArgs cea = (ConnectionEventArgs)args; if (cea.ConnectionType != ConnectionType.Structured) { //We don't do anything, return; } //This is the list we had when things changed ConnectionList structs = cea.CList; //structs is constant if (structs.Count == 0) { //There is no one to talk to return; } /* * Get the data we need about this connection: */ Connection con = cea.Connection; AHAddress new_address = (AHAddress)con.Address; /* * Update the left neighbor: */ Connection lc = structs.GetLeftNeighborOf(new_address); EnqueueAction(new UpdateNeighborAction(this, con.ConType, lc)); /* * Update the right neighbor: */ Connection rc = structs.GetRightNeighborOf(new_address); if (lc != rc) { EnqueueAction(new UpdateNeighborAction(this, con.ConType, rc)); } }
/** * Generates tree for bounded broadcast. Algorithm works as follows: * The goal is to broadcast to all nodes in range [local_address, end). * Given a range [local_address, b), determine all connections that belong to this range. * Let the connections be b_1, b_2, ..... b_n. * To connection bi assign the range [b_i, b_{i+1}). * To the connection bn assign range [b_n, end).] */ public override void GenerateTree(Channel q, MapReduceArgs mr_args) { object gen_arg = mr_args.GenArg; string end_range = gen_arg as string; Log("generating child tree, range end: {0}.", end_range); AHAddress end_addr = (AHAddress)AddressParser.Parse(end_range); AHAddress start_addr = _node.Address as AHAddress; //we are at the start node, here we go: ConnectionTable tab = _node.ConnectionTable; ConnectionList structs = tab.GetConnections(ConnectionType.Structured); ArrayList retval = new ArrayList(); if (structs.Count > 0) { Connection curr_con = structs.GetLeftNeighborOf(_node.Address); int curr_idx = structs.IndexOf(curr_con.Address); //keep going until we leave the range int count = 0; ArrayList con_list = new ArrayList(); while (count++ < structs.Count && ((AHAddress)curr_con.Address).IsBetweenFromLeft(start_addr, end_addr)) { con_list.Add(curr_con); //Log("adding connection: {0} to list.", curr_con.Address); curr_idx = (curr_idx + 1) % structs.Count; curr_con = structs[curr_idx]; } Log("{0}: {1}, number of child connections: {2}", this.TaskName, _node.Address, con_list.Count); for (int i = 0; i < con_list.Count; i++) { MapReduceInfo mr_info = null; ISender sender = null; Connection con = (Connection)con_list[i]; sender = (ISender)con.Edge; //check if last connection if (i == con_list.Count - 1) { mr_info = new MapReduceInfo((ISender)sender, new MapReduceArgs(this.TaskName, mr_args.MapArg, //map argument end_range, //generate argument mr_args.ReduceArg //reduce argument )); Log("{0}: {1}, adding address: {2} to sender list, range end: {3}", this.TaskName, _node.Address, con.Address, end_range); retval.Add(mr_info); } else { string child_end = ((Connection)con_list[i + 1]).Address.ToString(); mr_info = new MapReduceInfo(sender, new MapReduceArgs(this.TaskName, mr_args.MapArg, child_end, mr_args.ReduceArg)); Log("{0}: {1}, adding address: {2} to sender list, range end: {3}", this.TaskName, _node.Address, con.Address, child_end); retval.Add(mr_info); } } } q.Enqueue(retval.ToArray(typeof(MapReduceInfo))); }
/** * Sends a StatusMessage request (local node) to the nearest right and * left neighbors (in the local node's ConnectionTable) of the new Connection. */ protected void UpdateNeighborStatus(object contab, EventArgs args) { ConnectionEventArgs cea = (ConnectionEventArgs)args; if (cea.ConnectionType != ConnectionType.Structured) { //We don't do anything, return; } //This is the list we had when things changed ConnectionList structs = cea.CList; //structs is constant if (structs.Count == 0) { //There is no one to talk to return; } /* * Get the data we need about this connection: */ Connection con = cea.Connection; string con_type_string = con.ConType; AHAddress new_address = (AHAddress)con.Address; /* * Update the left neighbor: */ Connection lc = structs.GetLeftNeighborOf(new_address); try { //This edge could ahve been closed, which will //cause the Rpc to throw an exception CallGetStatus(con_type_string, lc); } catch (EdgeClosedException) { //Just ignore this connection if it is closed } catch (EdgeException ex) { if (!ex.IsTransient) { //Make sure this Edge is closed before going forward lc.Edge.Close(); } } catch (Exception x) { if (ProtocolLog.Exceptions.Enabled) { ProtocolLog.Write(ProtocolLog.Exceptions, String.Format( "CallGetStatus(left) on {0} failed: {1}", lc, x)); } } /* * Update the right neighbor: */ Connection rc = structs.GetRightNeighborOf(new_address); try { if ((lc != rc)) { //This edge could ahve been closed, which will //cause the Rpc to throw an exception CallGetStatus(con_type_string, rc); } } catch (EdgeClosedException) { //Just ignore this connection if it is closed } catch (EdgeException ex) { if (!ex.IsTransient) { //Make sure this Edge is closed before going forward rc.Edge.Close(); } } catch (Exception x) { if (ProtocolLog.Exceptions.Enabled) { ProtocolLog.Write(ProtocolLog.Exceptions, String.Format( "CallGetStatus(right) on {0} failed: {1}", rc, x)); } } }