Inheritance: Brunet.Concurrent.TaskWorker, ILinkLocker
Exemple #1
0
//////////////////
///
/// Protected/Private methods
///
/////////////////

        /**
         * @param success if this is true, we have a new edge to try else, make a new edge
         * @param target_ta the transport address this edge was created with
         * @param e the new edge, if success
         * @param x the exception which may be present if sucess is false
         */
        protected void EdgeWorkerHandler(object edgeworker, EventArgs args)
        {
            EdgeWorker ew         = (EdgeWorker)edgeworker;
            bool       close_edge = false;

            BC.TaskWorker next_task = null;
            try {
                Edge e = ew.NewEdge; //This can throw an exception
                SetTarget();         //This can also throw an exception

                //If we make it here, we did not have any problem.

                next_task              = new LinkProtocolState(this, ew.TA, e);
                next_task.FinishEvent += this.LinkProtocolStateFinishHandler;
            }
            catch (LinkException) {
                //This happens if SetTarget sees that we are already connected
                //Our only choice here is to close the edge and give up.
                close_edge = true;
            }
            catch (EdgeException) {
                /*
                 * If there is some problem creating the edge,
                 * we wind up here.  Just move on
                 */
                next_task = StartAttempt(NextTA());
            }
            catch (Exception ex) {
                /*
                 * The edge creation didn't work out so well
                 */
                BU.ProtocolLog.WriteIf(BU.ProtocolLog.LinkDebug, ex.ToString());
                next_task = StartAttempt(NextTA());
            }
            if (close_edge)
            {
                try {
                    ew.NewEdge.Close();
                }
                catch (Exception) {
                    //Ignore any exception
                }
            }
            if (next_task != null)
            {
                /*
                 * We should start a new task now
                 */
                _task_queue.Enqueue(next_task);
            }
        }
Exemple #2
0
//////////////////
///
/// Protected/Private methods
///
/////////////////
    
    /**
     * @param success if this is true, we have a new edge to try else, make a new edge
     * @param target_ta the transport address this edge was created with
     * @param e the new edge, if success
     * @param x the exception which may be present if sucess is false
     */
    protected void EdgeWorkerHandler(object edgeworker, EventArgs args)
    {
      EdgeWorker ew = (EdgeWorker)edgeworker;
      bool close_edge = false;
      BC.TaskWorker next_task = null;
      try {
        Edge e = ew.NewEdge; //This can throw an exception
        SetTarget(); //This can also throw an exception

        //If we make it here, we did not have any problem.
        
        next_task = new LinkProtocolState(this, ew.TA, e);
        next_task.FinishEvent +=  this.LinkProtocolStateFinishHandler;
        //Keep a proper track of the active LinkProtocolStates:
        Interlocked.Increment(ref _active_lps_count);
      }
      catch(ConnectionExistsException) {
        //We already have a connection to the target
        close_edge = true;
      }
      catch(LinkException) {
        //This happens if SetTarget sees that we are already connected
        //Our only choice here is to close the edge and give up.
        close_edge = true;
      }
      catch(CTLockException) {
        /*
         * SetTarget could not get the lock on the address.
         * Try again later
         */
        close_edge = true;
        next_task = GetRestartState( ew.TA );
        if( next_task == null ) {
          //We've restarted too many times:
          next_task = StartAttempt( NextTA() );
        }
      }
      catch(EdgeException) {
        /*
         * If there is some problem creating the edge,
         * we wind up here.  Just move on
         */
        next_task = StartAttempt( NextTA() );
      }
      catch(Exception ex) {
        /*
         * The edge creation didn't work out so well
         */
        BU.ProtocolLog.WriteIf(BU.ProtocolLog.LinkDebug, ex.ToString());
        next_task = StartAttempt( NextTA() );
      }
      if( close_edge ) {
        try {
          ew.NewEdge.Close();
        }
        catch(Exception) {
          //Ignore any exception
        }
      }
      if( next_task != null ) {
        /*
         * We should start a new task now
         */
        _task_queue.Enqueue(next_task);
      }
    }
Exemple #3
0
        protected void LinkProtocolStateFinishHandler(object olps, EventArgs args)
        {
            LinkProtocolState lps = (LinkProtocolState)olps;

#if LINK_DEBUG
            if (BU.ProtocolLog.LinkDebug.Enabled)
            {
                BU.ProtocolLog.Write(BU.ProtocolLog.LinkDebug,
                                     String.Format("{0}: Linker({1}): {2} finished with result: {3} at: {4}",
                                                   _local_n.Address, _lid, lps, lps.MyResult, DateTime.UtcNow));
            }
#endif
            BC.TaskWorker next_task = null;
            switch (lps.MyResult)
            {
            case LinkProtocolState.Result.Success:
                /*
                 * Great, the Connection is up and in our table now
                 * Just do nothing now and wait for the other tasks
                 * to finish, at which point, the Linker will fire
                 * its FinishEvent.
                 */
                Interlocked.Increment(ref _added_cons);
#if LINK_DEBUG
                if (BU.ProtocolLog.LinkDebug.Enabled)
                {
                    BU.ProtocolLog.Write(BU.ProtocolLog.LinkDebug,
                                         String.Format("{0}: Linker({1}) added {2} at: {3}", _local_n.Address,
                                                       _lid, lps.Connection, DateTime.UtcNow));
                }
#endif
                break;

            case LinkProtocolState.Result.RetryThisTA:
                next_task = GetRestartState(lps.TA);
                if (next_task == null)
                {
                    goto case LinkProtocolState.Result.MoveToNextTA;
                }
                break;

            case LinkProtocolState.Result.MoveToNextTA:
                //Hold the lock, it will be transferred:
                // old LPS -> Linker -> new LPS
                next_task = StartAttempt(NextTA());
                break;

            case LinkProtocolState.Result.ProtocolError:
                break;

            case LinkProtocolState.Result.Exception:
                break;

            default:
                //This should not happen.
                Console.Error.WriteLine("unrecognized result: " + lps.MyResult.ToString());
                break;
            }
            if (next_task != null)
            {
                //We have some new task to start
                _task_queue.Enqueue(next_task);
            }
            int current_active = Interlocked.Decrement(ref _active_lps_count);
            if (current_active == 0)
            {
                //We have finished handling this lps finishing,
                //if we have not started another yet, we are not
                //going to right away.  In the mean time, release
                //the lock
                Unlock();
            }
        }
Exemple #4
0
//////////////////
///
/// Protected/Private methods
///
/////////////////

        /**
         * @param success if this is true, we have a new edge to try else, make a new edge
         * @param target_ta the transport address this edge was created with
         * @param e the new edge, if success
         * @param x the exception which may be present if sucess is false
         */
        protected void EdgeWorkerHandler(object edgeworker, EventArgs args)
        {
            EdgeWorker ew         = (EdgeWorker)edgeworker;
            bool       close_edge = false;

            BC.TaskWorker next_task = null;
            try {
                Edge e = ew.NewEdge; //This can throw an exception
                SetTarget();         //This can also throw an exception

                //If we make it here, we did not have any problem.

                next_task              = new LinkProtocolState(this, ew.TA, e);
                next_task.FinishEvent += this.LinkProtocolStateFinishHandler;
                //Keep a proper track of the active LinkProtocolStates:
                Interlocked.Increment(ref _active_lps_count);
            }
            catch (ConnectionExistsException) {
                //We already have a connection to the target
                close_edge = true;
            }
            catch (LinkException) {
                //This happens if SetTarget sees that we are already connected
                //Our only choice here is to close the edge and give up.
                close_edge = true;
            }
            catch (CTLockException) {
                /*
                 * SetTarget could not get the lock on the address.
                 * Try again later
                 */
                close_edge = true;
                next_task  = GetRestartState(ew.TA);
                if (next_task == null)
                {
                    //We've restarted too many times:
                    next_task = StartAttempt(NextTA());
                }
            }
            catch (EdgeException) {
                /*
                 * If there is some problem creating the edge,
                 * we wind up here.  Just move on
                 */
                next_task = StartAttempt(NextTA());
            }
            catch (Exception ex) {
                /*
                 * The edge creation didn't work out so well
                 */
                BU.ProtocolLog.WriteIf(BU.ProtocolLog.LinkDebug, ex.ToString());
                next_task = StartAttempt(NextTA());
            }
            if (close_edge)
            {
                try {
                    ew.NewEdge.Close();
                }
                catch (Exception) {
                    //Ignore any exception
                }
            }
            if (next_task != null)
            {
                /*
                 * We should start a new task now
                 */
                _task_queue.Enqueue(next_task);
            }
        }
Exemple #5
0
        /**
         * Allow if we are transfering to a LinkProtocolState or ConnectionPacketHandler
         * Note this method does not change anything, if the transfer is done, it
         * is done by the ConnectionTable while it holds its lock.
         */
        public bool AllowLockTransfer(Address a, string contype, ILinkLocker l)
        {
            bool allow     = false;
            bool hold_lock = (a.Equals(_target_lock) && contype == _contype);

            if (false == hold_lock)
            {
                //We don't even hold this lock!
                throw new Exception(
                          String.Format("{2} asked to transfer a lock({0}) we don't hold: ({1})",
                                        a, _target_lock, this));
            }
            if (l is Linker)
            {
                //Never transfer to another linker:
            }
            else if (l is ConnectionPacketHandler.CphState)
            {
                /**
                 * The ConnectionPacketHandler only locks when it
                 * has actually received a packet.  This is a "bird in the
                 * hand" situation, however, if both sides in the double
                 * link case transfer the lock, then we have accomplished
                 * nothing.
                 *
                 * There is a specific case to worry about: the case of
                 * a firewall, where only one node can contact the other.
                 * In this case, it may be very difficult to connect if
                 * we don't eventually transfer the lock to the
                 * ConnectionPacketHandler.  In the case of bi-directional
                 * connectivity, we only transfer the lock if the
                 * address we are locking is greater than our own (which
                 * clearly cannot be true for both sides).
                 *
                 * To handle the firewall case, we keep count of how
                 * many times we have been asked to transfer the lock.  On
                 * the third time we are asked, we assume we are in the firewall
                 * case and we allow the transfer, this is just a hueristic.
                 */
                int reqs = Interlocked.Increment(ref _cph_transfer_requests);
                if ((reqs >= 3) || (a.CompareTo(LocalNode.Address) > 0))
                {
                    allow = true;
                }
            }
            else if (l is LinkProtocolState)
            {
                LinkProtocolState lps = (LinkProtocolState)l;

                /**
                 * Or Transfer the lock to a LinkProtocolState if:
                 * 1) We created this LinkProtocolState
                 * 2) The LinkProtocolState has received a packet
                 */
                if ((lps.Linker == this) && (lps.LinkMessageReply != null))
                {
                    allow = true;
                }
            }
#if LINK_DEBUG
            if (BU.ProtocolLog.LinkDebug.Enabled)
            {
                BU.ProtocolLog.Write(BU.ProtocolLog.LinkDebug,
                                     String.Format("{0}: Linker({1}) {2}: transfering lock on {3} to {4}",
                                                   _local_n.Address, _lid, (_target_lock == null), a, l));
            }
#endif
            return(allow);
        }
Exemple #6
0
//////////////////
///
/// Protected/Private methods
///
/////////////////
    
    /**
     * @param success if this is true, we have a new edge to try else, make a new edge
     * @param target_ta the transport address this edge was created with
     * @param e the new edge, if success
     * @param x the exception which may be present if sucess is false
     */
    protected void EdgeWorkerHandler(object edgeworker, EventArgs args)
    {
      EdgeWorker ew = (EdgeWorker)edgeworker;
      bool close_edge = false;
      BC.TaskWorker next_task = null;
      try {
        Edge e = ew.NewEdge; //This can throw an exception
        SetTarget(); //This can also throw an exception

        //If we make it here, we did not have any problem.
        
        next_task = new LinkProtocolState(this, ew.TA, e);
        next_task.FinishEvent +=  this.LinkProtocolStateFinishHandler;
      }
      catch(LinkException) {
        //This happens if SetTarget sees that we are already connected
        //Our only choice here is to close the edge and give up.
        close_edge = true;
      }
      catch(EdgeException) {
        /*
         * If there is some problem creating the edge,
         * we wind up here.  Just move on
         */
        next_task = StartAttempt( NextTA() );
      }
      catch(Exception ex) {
        /*
         * The edge creation didn't work out so well
         */
        BU.ProtocolLog.WriteIf(BU.ProtocolLog.LinkDebug, ex.ToString());
        next_task = StartAttempt( NextTA() );
      }
      if( close_edge ) {
        try {
          ew.NewEdge.Close();
        }
        catch(Exception) {
          //Ignore any exception
        }
      }
      if( next_task != null ) {
        /*
         * We should start a new task now
         */
        _task_queue.Enqueue(next_task);
      }
    }