public void ComputePathLatencyTo(AHAddress a, object req_state) {
/*
* First find the Connection pointing to the node closest to dest, if
* there is one closer than us
*/
ConnectionTable tab = _node.ConnectionTable;
ConnectionList structs = tab.GetConnections(ConnectionType.Structured);
Connection next_closest = structs.GetNearestTo((AHAddress) _node.Address, a);
//Okay, we have the next closest:
ListDictionary my_entry = new ListDictionary();
my_entry["node"] = _node.Address.ToString();
if( next_closest != null ) {
my_entry["next_latency"] = GetMeasuredLatency(next_closest.Address);
my_entry["next_contype"] = next_closest.ConType;
Channel result = new Channel();
//We only want one result, so close the queue after we get the first
result.CloseAfterEnqueue();
result.CloseEvent += delegate(object o, EventArgs args) {
Channel q = (Channel)o;
if( q.Count > 0 ) {
try {
RpcResult rres = (RpcResult)q.Dequeue();
IList l = (IList) rres.Result;
ArrayList results = new ArrayList( l.Count + 1);
results.Add(my_entry);
results.AddRange(l);
_rpc.SendResult(req_state, results);
}
catch(Exception x) {
string m = String.Format("<node>{0}</node> trying <connection>{1}</connection> got <exception>{2}</exception>", _node.Address, next_closest, x);
Exception nx = new Exception(m);
_rpc.SendResult(req_state, nx);
}
}
else {
//We got no results.
IList l = new ArrayList(1);
l.Add( my_entry );
_rpc.SendResult(req_state, l);
}
};
try {
_rpc.Invoke(next_closest.State.Edge, result, "ncserver.ComputePathLatencyTo", a.ToString());
}
catch(Exception x) {
//We must always return from an RPC call, and this is one:
_rpc.SendResult(req_state, x);
}
}
else {
//We are the end of the line, send the result:
ArrayList l = new ArrayList();
l.Add(my_entry);
_rpc.SendResult(req_state, l);
}
}