public override void Activate()
{
#if POB_DEBUG
Console.Error.WriteLine("In Activate: {0}", _node.Address);
#endif
if( IsActive == false ) {
return;
}
DateTime now = DateTime.UtcNow;
lock( _sync ) {
if( now - _last_retry_time < _current_retry_interval ) {
//Not time yet...
return;
}
_last_retry_time = now;
//Double the length of time we wait (resets to default on connections)
_current_retry_interval += _current_retry_interval;
_current_retry_interval = (_MAX_RETRY_INTERVAL < _current_retry_interval) ?
_MAX_RETRY_INTERVAL : _current_retry_interval;
}
ConnectionTable tab = _node.ConnectionTable;
//If we are going to connect to someone, this is how we
//know who to use
Address target = null;
string contype = String.Empty;
ISender sender = null;
int desired_ctms = 1;
ConnectionList structs = tab.GetConnections(ConnectionType.Structured);
if( structs.Count < 2 ) {
ConnectionList leafs = tab.GetConnections(ConnectionType.Leaf);
if( leafs.Count == 0 )
{
/*
* We first need to get a Leaf connection
*/
return;
}
//We don't have enough connections to guarantee a connected
//graph. Use a leaf connection to get another connection
Connection leaf = null;
//Make sure the following loop can't go on forever
int attempts = 2 * leafs.Count;
do {
leaf = leafs[ _rand.Next( leafs.Count ) ];
attempts--;
}
while( leafs.Count > 1 && structs.Contains( leaf.Address ) &&
attempts > 0 );
//Now we have a random leaf that is not a
//structured neighbor to try to get a new neighbor with:
if( leaf != null ) {
target = GetSelfTarget();
/*
* This is the case of trying to find the nodes nearest
* to ourselves, use the Annealing routing to get connected
* more quickly
*/
sender = new ForwardingSender(_node, leaf.Address, target);
//We are trying to connect to the two nearest nodes in one
//one attempt, so wait for two distinct responses:
desired_ctms = 2;
//This is a near neighbor connection
contype = STRUC_NEAR;
}
}
if( structs.Count > 0 && sender == null ) {
/**
* We need left or right neighbors we send
* a ConnectToMessage in the directons we
* need.
*/
if( NeedLeftNeighbor ) {
#if POB_DEBUG
Console.Error.WriteLine("NeedLeftNeighbor: {0}", _node.Address);
#endif
target = new DirectionalAddress(DirectionalAddress.Direction.Left);
short ttl = (short)DESIRED_NEIGHBORS;
sender = new AHSender(_node, target, ttl, AHHeader.Options.Last);
contype = STRUC_NEAR;
} else if( NeedRightNeighbor ) {
#if POB_DEBUG
Console.Error.WriteLine("NeedRightNeighbor: {0}", _node.Address);
#endif
target = new DirectionalAddress(DirectionalAddress.Direction.Right);
short ttl = (short)DESIRED_NEIGHBORS;
sender = new AHSender(_node, target, ttl, AHHeader.Options.Last);
contype = STRUC_NEAR;
}
}
if( sender != null ) {
ConnectTo(sender, target, contype, desired_ctms);
}
}