Inheritance: Brunet.Concurrent.TaskWorker
Example #1
0
 /**
  * This is a method for use with the RpcManager.  Remote
  * nodes can call the "sys:ctm.ConnectTo" method to 
  * reach this method
  */
 public IDictionary ConnectTo(IDictionary ht) {
   ConnectToMessage ctm_req = new ConnectToMessage(ht);
   //Console.Error.WriteLine("[{0}.ConnectTo({1})]", _n.Address, ctm_req);
   NodeInfo target = ctm_req.Target;
   if(_n.Address.Equals(target.Address)) {
     throw new Exception("Trying to connect to myself!");
   }
   string contype = ctm_req.ConnectionType;
   Linker l = new Linker(_n, target.Address, target.Transports, contype, ctm_req.Token);
   //Here we start the job:
   _n.TaskQueue.Enqueue( l );
   ConnectToMessage resp = GetCtmResponseTo(ctm_req);
   //Console.Error.WriteLine("[{0}.ConnectTo()->{1}]", _n.Address, resp);
   return resp.ToDictionary();
 }
        /// <summary>If we get here, the Linker has completed, we are either
        /// connected or need to reattempt the connection.</summary>
        override protected void LinkerEndHandler(object o, EventArgs eargs)
        {
            if (!IsActive)
            {
                return;
            }
            Linker     linker = o as Linker;
            Address    addr   = linker.Target;
            Connection con    = _node.ConnectionTable.GetConnection(MainType, addr);

            if (con == null)
            {
                FailedConnectionAttempt(addr);
            }
            else
            {
                ObtainedConnection(con);
            }
        }
Example #3
0
        /**
         * This is a method for use with the RpcManager.  Remote
         * nodes can call the "sys:ctm.ConnectTo" method to
         * reach this method
         */
        public IDictionary ConnectTo(IDictionary ht)
        {
            ConnectToMessage ctm_req = new ConnectToMessage(ht);
            //Console.Error.WriteLine("[{0}.ConnectTo({1})]", _n.Address, ctm_req);
            NodeInfo target = ctm_req.Target;

            if (_n.Address.Equals(target.Address))
            {
                throw new Exception("Trying to connect to myself!");
            }
            string contype = ctm_req.ConnectionType;
            Linker l       = new Linker(_n, target.Address, target.Transports, contype, ctm_req.Token);

            //Here we start the job:
            _n.TaskQueue.Enqueue(l);
            ConnectToMessage resp = GetCtmResponseTo(ctm_req);

            //Console.Error.WriteLine("[{0}.ConnectTo()->{1}]", _n.Address, resp);
            return(resp.ToDictionary());
        }
Example #4
0
        /**
         * This method allows a user to add some state in the ConnectTo call (see SNCO).
         */
        virtual protected Connector GetConnector(ISender sender, Address target,
                                                 string ConnectionType, string token)
        {
            ConnectionType mt = Connection.StringToMainType(ConnectionType);

            /*
             * This is an anonymous delegate which is called before
             * the Connector starts.  If it returns true, the Connector
             * will finish immediately without sending an ConnectToMessage
             */
            Linker l = new Linker(_node, target, null, ConnectionType,
                                  _node.Address.ToString());
            object link_task = l.Task;

            Connector.AbortCheck abort = delegate(Connector c) {
                bool stop = false;
                stop = _node.ConnectionTable.Contains(mt, target);
                if (!stop)
                {
                    /*
                     * Make a linker to get the task.  We won't use
                     * this linker.
                     * No need in sending a ConnectToMessage if we
                     * already have a linker going.
                     */
                    stop = _node.TaskQueue.HasTask(link_task);
                }
                return(stop);
            };

            ConnectToMessage ctm = GetConnectToMessage(ConnectionType, token);
            Connector        con = new Connector(_node, sender, ctm, this, target);

            con.FinishEvent += ConnectorEndHandler;
            con.AbortIf      = abort;
            return(con);
        }
Example #5
0
 public RestartState(Linker l, TransportAddress ta)
        : this(l, ta, _MAX_RESTARTS) {
 }
Example #6
0
 public RestartState(Linker l, TransportAddress ta,
                     int remaining_attempts) {
   _linker = l;
   _ta = ta;
   _restart_attempts = remaining_attempts;
   _first_start = 1; 
 }
Example #7
0
 public LinkProtocolState(Linker l, TransportAddress ta, Edge e) {
   _linker = l;
   _node = l.LocalNode;
   _contype = l.ConType;
   _target_lock = null;
   _lm_reply = new WriteOnce<LinkMessage>();
   _x = new WriteOnce<Exception>();
   _con = new WriteOnce<Connection>();
   _ta = ta;
   _is_finished = 0;
   //Setup the edge:
   _e = e;
   _result = Result.None;
 }
Example #8
0
 public RestartState(Linker l, TransportAddress ta)
     : this(l, ta, _MAX_RESTARTS)
 {
 }
Example #9
0
 /**
  * When a Linker finishes, this method is called.  This is
  * to do memory management of the Linker objects
  */
 protected void LinkerFinishHandler(object linker, EventArgs args)
 {
   //We need to remove this linker from our list:
   lock( _sync ) {
     _linker = null;
   }
 }
Example #10
0
    /**
     * Linker objects call this when they are done, and we start
     * again if we need to
     */
    public void CheckAndConnectHandler(object linker, EventArgs args)
    {
      ConnectionEventArgs cea = args as ConnectionEventArgs;
      DateTime now = DateTime.UtcNow;
      Linker new_linker = null;
      lock(_sync) {
        if( cea != null ) {
          //This is a connection event.
          if( cea.Connection.MainType != ConnectionType.Leaf ) {
            _last_non_leaf_connection_event = now;
          }
        }
        //Check in order of cheapness, so we can avoid hard work...
        bool time_to_start = (now - _last_retry >= _current_retry_interval );
        if ( (_linker == null) && time_to_start && 
             IsActive && NeedConnection ) {
          //Now we double the retry interval.  When we get a connection
          //We reset it back to the default value:
          _last_retry = now;
          _current_retry_interval += _current_retry_interval;
          _current_retry_interval = (_MAX_RETRY_INTERVAL < _current_retry_interval) ?
              _MAX_RETRY_INTERVAL : _current_retry_interval;

          //Get a random address to connect to:
  
          //Make a copy:
          object[] tas = (new List<TransportAddress>(_local.RemoteTAs)).ToArray();
          /*
           * Make a randomized list of TransportAddress objects to connect to:
           * This is a very nice algorithm.  It is optimal in that it produces
           * a permutation of a list using N swaps and log(N!) bits
           * of entropy.
           */
          for(int j = 0; j < tas.Length; j++) {
            //Swap the j^th position with this position:
            int i = _rnd.Next(j, tas.Length);
              if( i != j ) {
              object temp_ta = tas[i];
              tas[i] = tas[j];
                tas[j] = temp_ta;
              }
          }
          /**
           * Make a Link to a remote node 
           */
          _linker = new Linker(_local, null, tas, "leaf", _local.Address.ToString());
          new_linker = _linker;
        }
        else if (cea != null) {
          /*
           * This is the case that there was a non-leaf connection
           * or disconnection, BUT it is not yet time to start OR
           * there is current linker running OR we are not active OR
           * we don't need a connection
           * 
           * In this case, we set the retry interval back to the default
           * value.  This is because we only do the exponential back
           * off when there we can't seem to get connected when we try.
           * Clearly we are getting edges here, so there is no need
           * for the back-off.
           */

          //Reset the connection interval to the default value:
            _current_retry_interval = _default_retry_interval;
          //We are not seeking another connection
          //log.Info("LeafConnectionOverlord :  not seeking connection");
        }
        //Check to see if it is time to trim.
      }//Drop the lock
      Trim();
      
      /**
       * If there is a new linker, start it after we drop the lock
       */
      if( new_linker != null ) {
        new_linker.FinishEvent += this.LinkerFinishHandler;
        new_linker.Start();
      }
    }
Example #11
0
    public LeafConnectionOverlord(Node local)
    {
      _compensate = 0;
      _local = local;
      _linker = null;
      _sync = new object();
#if BRUNET_SIMULATOR
      _rnd = Node.SimulatorRandom;
#else
      _rnd = new Random( _local.GetHashCode()
                         ^ unchecked((int)DateTime.UtcNow.Ticks) );
#endif
      _default_retry_interval = new TimeSpan(0,0,0,0,10000);
      _current_retry_interval = new TimeSpan(0,0,0,0,10000);
      //We initialize at at year 1 to start with:
      _last_retry = DateTime.MinValue;
      _last_non_leaf_connection_event = DateTime.MinValue;
      _last_trim = DateTime.MinValue;
      /*
       * When a node is removed from the ConnectionTable,
       * we should check to see if we need to work to get a
       * replacement
       */
      lock(_sync) {
        local.ConnectionTable.DisconnectionEvent += this.CheckAndConnectHandler;
        local.ConnectionTable.ConnectionEvent += this.CheckAndConnectHandler;
        /**
         * Every heartbeat we check to see if we need to act
         */
        local.HeartBeatEvent += this.CheckAndConnectHandler;
      }
    }
Example #12
0
    /// <summary>Make sure there are no entries in the Dht, who we should be
    /// connected to, but aren't.</summary>
    protected void CheckAndUpdateRemoteTAs(List<TransportAddress> tas)
    {
      AHAddress right = null, left = null;
      BigInteger right_dist = null, left_dist = null;
      AHAddress addr = _node.Address as AHAddress;

      // Find the closest left and right nodes
      foreach(TransportAddress ta in tas) {
        AHAddress target = (ta as SubringTransportAddress).Target;
        if(target.Equals(addr)) {
          continue;
        }
        BigInteger ldist = addr.LeftDistanceTo(target);
        BigInteger rdist = addr.RightDistanceTo(target);

        if(left_dist == null || ldist < left_dist) {
          left_dist = ldist;
          left = target;
        }

        if(right_dist == null || rdist < right_dist) {
          right_dist = rdist;
          right = target;
        }
      }

      ConnectionList cl = _node.ConnectionTable.GetConnections(ConnectionType.Structured);
      int local_idx = ~cl.IndexOf(_node.Address);

      if(left != null) {
        int remote_idx = ~cl.IndexOf(left);
        // If we're not connected to the left closest and its closer than any
        // of our current peers, let's connect to it
        if(remote_idx > 0 && Math.Abs(local_idx - remote_idx) < 2) {
          List<TransportAddress> tmp_tas = new List<TransportAddress>(1);
          tmp_tas.Add(new SubringTransportAddress(left, _shared_namespace));
          Linker linker = new Linker(_node, null, tmp_tas, "leaf", addr.ToString());
          linker.Start();
        }
      }

      if(right != null && right != left) {
        int remote_idx = ~cl.IndexOf(right);
        // If we're not connected to the right closest and its closer than any
        // of our current peers, let's connect to it
        if(remote_idx > 0 && Math.Abs(local_idx - remote_idx) < 2) {
          List<TransportAddress> tmp_tas = new List<TransportAddress>(1);
          tas.Add(new SubringTransportAddress(right, _shared_namespace));
          Linker linker = new Linker(_node, null, tmp_tas, "leaf", addr.ToString());
          linker.Start();
        }
      }

      UpdateRemoteTAs(tas);
    }