Пример #1
0
        /**
         * This creates a TaskWorker that represents the next step that should
         * be taken for the ta.  It can only be two tasks: create the edge
         * (EdgeWorker) or wait and try again (RestartState).
         *
         * We return null if:
         *  - the TA is null
         *  - Linker is finished
         *  - a Connection was already created
         *  - this TA has been restarted too many times
         *
         * If we cannot get a ConnectionTable.Lock with SetTarget, we return a
         * RestartState to wait a little while to try to get the lock again.
         *
         * @returns the next TaskWorker that should be enqueued, does not start or
         * Enqueue it.
         */
        protected BC.TaskWorker StartAttempt(TransportAddress next_ta)
        {
            BC.TaskWorker next_task = null;
            if ((next_ta == null) || (_added_cons != 0) || IsFinished || ConnectionInTable)
            {
                //Looks like we are already connected...
                return(null);
            }
            try {
#if LINK_DEBUG
                if (BU.ProtocolLog.LinkDebug.Enabled)
                {
                    BU.ProtocolLog.Write(BU.ProtocolLog.LinkDebug,
                                         String.Format("{0}: Linker ({1}) attempting to lock {2}", _local_n.Address, _lid, _target));
                }
#endif

                /*
                 * If we cannot set this address as our target, we
                 * stop before we even try to make an edge.
                 *
                 * Locks flow around in complex ways, but we
                 * (or one of our LinkProtocolState)
                 * will hold the lock
                 */
                SetTarget();
#if LINK_DEBUG
                if (BU.ProtocolLog.LinkDebug.Enabled)
                {
                    BU.ProtocolLog.Write(BU.ProtocolLog.LinkDebug,
                                         String.Format("{0}: Linker ({1}) acquired lock on {2}", _local_n.Address, _lid, _target));
                    BU.ProtocolLog.Write(BU.ProtocolLog.LinkDebug,
                                         String.Format("{0}: Linker: ({1}) Trying TA: {2}", _local_n.Address, _lid, next_ta));
                }
#endif
                next_task              = new EdgeWorker(_local_n, next_ta);
                next_task.FinishEvent += this.EdgeWorkerHandler;
            }
            catch (CTLockException) {
                /*
                 * If we cannot get a lock on the address in SetTarget()
                 * we wait and and try again
                 */
#if LINK_DEBUG
                if (BU.ProtocolLog.LinkDebug.Enabled)
                {
                    BU.ProtocolLog.Write(BU.ProtocolLog.LinkDebug,
                                         String.Format("{0}: Linker ({1}) failed to lock {2}", _local_n.Address, _lid, _target));
                }
#endif
                next_task = GetRestartState(next_ta);
            }
            catch (ConnectionExistsException) {
                //We already have a connection to the target
            }
            catch (Exception) {
            }
            return(next_task);
        }
Пример #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;
            }
            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);
            }
        }
Пример #3
0
    /**
     * This creates a TaskWorker that represents the next step that should
     * be taken for the ta.  It can only be two tasks: create the edge
     * (EdgeWorker) or wait and try again (RestartState).
     *
     * We return null if:
     *  - the TA is null
     *  - Linker is finished
     *  - a Connection was already created
     *  - this TA has been restarted too many times
     *
     * If we cannot get a ConnectionTable.Lock with SetTarget, we return a
     * RestartState to wait a little while to try to get the lock again.
     *
     * @returns the next TaskWorker that should be enqueued, does not start or
     * Enqueue it.
     */
    protected TaskWorker StartAttempt(TransportAddress next_ta) {
      TaskWorker next_task = null;
      if ( (next_ta == null) || (_added_cons != 0) || IsFinished || ConnectionInTable ) {
        //Looks like we are already connected...
        return null;
      }
      try {
#if LINK_DEBUG
        if (ProtocolLog.LinkDebug.Enabled) {
          ProtocolLog.Write(ProtocolLog.LinkDebug, 
            String.Format("{0}: Linker ({1}) attempting to lock {2}", _local_n.Address, _lid, _target));
        }
#endif
        /*
         * If we cannot set this address as our target, we
         * stop before we even try to make an edge.
          * 
          * Locks flow around in complex ways, but we
          * (or one of our LinkProtocolState)
          * will hold the lock
          */
        SetTarget();
#if LINK_DEBUG
        if (ProtocolLog.LinkDebug.Enabled) {
            ProtocolLog.Write(ProtocolLog.LinkDebug, 
			        String.Format("{0}: Linker ({1}) acquired lock on {2}", _local_n.Address, _lid, _target));
            ProtocolLog.Write(ProtocolLog.LinkDebug, 
              String.Format("{0}: Linker: ({1}) Trying TA: {2}", _local_n.Address, _lid, next_ta));
        }
#endif
        next_task = new EdgeWorker(_local_n, next_ta);
        next_task.FinishEvent += this.EdgeWorkerHandler;
      }
      catch(CTLockException) {
        /*
         * If we cannot get a lock on the address in SetTarget()
         * we wait and and try again
         */
#if LINK_DEBUG
        if (ProtocolLog.LinkDebug.Enabled) {
          ProtocolLog.Write(ProtocolLog.LinkDebug, 
            String.Format("{0}: Linker ({1}) failed to lock {2}", _local_n.Address, _lid, _target));
        }
#endif
        next_task = GetRestartState(next_ta);
      }
      catch(ConnectionExistsException) {
        //We already have a connection to the target
      }
      catch(Exception) {

      }
      return next_task;
    }
Пример #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);
            }
        }