virtual protected void CheckEdgesCallback(object node, EventArgs args)
{
DateTime now = DateTime.UtcNow;
//_connection_timeout = ComputeDynamicTimeout();
_connection_timeout = MAX_CONNECTION_TIMEOUT;
/*
* If we haven't heard from any of these people in this time,
* we ping them, and if we don't get a response, we close them
*/
foreach(Connection c in _connection_table) {
Edge e = c.State.Edge;
TimeSpan since_last_in = now - e.LastInPacketDateTime;
if( (1 == _send_pings) && ( since_last_in > _connection_timeout ) ) {
object ping_arg = String.Empty;
DateTime start = DateTime.UtcNow;
EventHandler on_close = delegate(object q, EventArgs cargs) {
BCon.Channel qu = (BCon.Channel)q;
if( qu.Count == 0 ) {
/* we never got a response! */
if( !e.IsClosed ) {
//We are going to close it after waiting:
ProtocolLog.WriteIf(ProtocolLog.Connections, String.Format(
"On an edge timeout({1}), closing connection: {0}",
c, DateTime.UtcNow - start));
//Make sure it is indeed closed.
e.Close();
}
else {
//The edge was closed somewhere else, so it
//didn't timeout.
}
}
else {
//We got a response, let's make sure it's not an exception:
bool close = false;
try {
RpcResult r = (RpcResult)qu.Dequeue();
object o = r.Result; //This will throw an exception if there was a problem
if( !o.Equals( ping_arg ) ) {
//Something is wrong with the other node:
ProtocolLog.WriteIf(ProtocolLog.NodeLog, String.Format(
"Ping({0}) != {1} on {2}", ping_arg, o, c));
close = true;
}
}
catch(Exception x) {
ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format(
"Ping on {0}: resulted in: {1}", c, x));
close = true;
}
if( close ) { e.Close(); }
}
};
BCon.Channel tmp_queue = new BCon.Channel(1);
tmp_queue.CloseEvent += on_close;
//Do the ping
try {
_rpc.Invoke(e, tmp_queue, "sys:link.Ping", ping_arg);
}
catch(EdgeClosedException) {
//Just ignore closed edges, clearly we can't ping them
}
catch(EdgeException x) {
if(!x.IsTransient) {
//Go ahead and close the Edge
e.Close();
}
}
}
}
foreach(Edge e in _connection_table.GetUnconnectedEdges() ) {
if( now - e.LastInPacketDateTime > _unconnected_timeout ) {
if(ProtocolLog.Connections.Enabled)
ProtocolLog.Write(ProtocolLog.Connections, String.Format(
"Closed an unconnected edge: {0}", e));
e.Close();
}
}
}