Example #1
0
        internal void SetAgentArrivedAtDestination(UUID id)
        {
            lock (m_agentsInTransit)
            {
                if (!m_agentsInTransit.ContainsKey(id))
                {
                    m_log.WarnFormat(
                        "[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but no teleport request is active",
                        m_mod.Scene.RegionInfo.RegionName, id);

                    return;
                }

                AgentTransferState currentState = m_agentsInTransit[id];

                if (currentState == AgentTransferState.ReceivedAtDestination)
                {
                    // An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification.
                    m_log.WarnFormat(
                        "[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but notification has already previously been received",
                        m_mod.Scene.RegionInfo.RegionName, id);
                }
                else if (currentState != AgentTransferState.Transferring)
                {
                    m_log.ErrorFormat(
                        "[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but agent is in state {2}",
                        m_mod.Scene.RegionInfo.RegionName, id, currentState);

                    return;
                }

                m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination;
            }
        }
        /// <summary>
        /// Updates the state of an agent that is already in transit.
        /// </summary>
        /// <param name='id'></param>
        /// <param name='newState'></param>
        /// <returns></returns>
        /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
        internal void UpdateInTransit(UUID id, AgentTransferState newState)
        {
            lock (m_agentsInTransit)
            {
                // Illegal to try and update an agent that's not actually in transit.
                if (!m_agentsInTransit.ContainsKey(id))
                {
                    throw new Exception(
                              string.Format(
                                  "Agent with ID {0} is not registered as in transit in {1}",
                                  id, m_mod.Scene.RegionInfo.RegionName));
                }

                AgentTransferState oldState = m_agentsInTransit[id];

                bool transitionOkay = false;

                if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
                {
                    transitionOkay = true;
                }
                else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
                {
                    transitionOkay = true;
                }
                else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
                {
                    transitionOkay = true;
                }

                if (transitionOkay)
                {
                    m_agentsInTransit[id] = newState;
                }
                else
                {
                    throw new Exception(
                              string.Format(
                                  "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
                                  id, oldState, newState, m_mod.Scene.RegionInfo.RegionName));
                }
            }
        }
        internal bool WaitForAgentArrivedAtDestination(UUID id)
        {
            if (!m_mod.WaitForAgentArrivedAtDestination)
            {
                return(true);
            }

            lock (m_agentsInTransit)
            {
                if (!IsInTransit(id))
                {
                    throw new Exception(
                              string.Format(
                                  "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit",
                                  id, m_mod.Scene.RegionInfo.RegionName));
                }

                AgentTransferState currentState = m_agentsInTransit[id];

                if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination)
                {
                    throw new Exception(
                              string.Format(
                                  "Asked to wait for destination callback for agent with ID {0} in {1} but agent is in state {2}",
                                  id, m_mod.Scene.RegionInfo.RegionName, currentState));
                }
            }

            int count = 200;

            // There should be no race condition here since no other code should be removing the agent transfer or
            // changing the state to another other than Transferring => ReceivedAtDestination.
            while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0)
            {
//                m_log.Debug("  >>> Waiting... " + count);
                Thread.Sleep(100);
            }

            return(count > 0);
        }
Example #4
0
        /// <summary>
        /// Removes an agent from the transit state machine.
        /// </summary>
        /// <param name='id'></param>
        /// <returns>true if the agent was flagged as being teleported when this method was called, false otherwise</returns>
        internal bool ResetFromTransit(UUID id)
        {
            lock (m_agentsInTransit)
            {
                if (m_agentsInTransit.ContainsKey(id))
                {
                    AgentTransferState state = m_agentsInTransit[id];

//                    if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination)
//                    {
                    // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed
                    // to be handled properly - ResetFromTransit() could be invoked at any step along the process
//                        m_log.WarnFormat(
//                            "[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}",
//                            id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName);

//                        throw new Exception(
//                            "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first",
//                            state, AgentTransferState.CleaningUp);
//                    }

                    m_agentsInTransit.Remove(id);

//                    m_log.DebugFormat(
//                        "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}",
//                        id, m_mod.Scene.RegionInfo.RegionName);

                    return(true);
                }
            }

//            m_log.WarnFormat(
//                "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared",
//                id, m_mod.Scene.RegionInfo.RegionName);

            return(false);
        }
Example #5
0
        /// <summary>
        /// Updates the state of an agent that is already in transit.
        /// </summary>
        /// <param name='id'></param>
        /// <param name='newState'></param>
        /// <returns></returns>
        /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
        internal bool UpdateInTransit(UUID id, AgentTransferState newState)
        {
            //           m_log.DebugFormat("{0} UpdateInTransit. agent={1}, newState={2}", LogHeader, id, newState);

            bool transitionOkay = false;

            // We don't want to throw an exception on cancel since this can come it at any time.
            bool failIfNotOkay = true;

            // Should be a failure message if failure is not okay.
            string failureMessage = null;

            AgentTransferState?oldState = null;

            lock (m_agentsInTransit)
            {
                // Illegal to try and update an agent that's not actually in transit.
                if (!m_agentsInTransit.ContainsKey(id))
                {
                    if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting)
                    {
                        failureMessage = string.Format(
                            "Agent with ID {0} is not registered as in transit in {1}",
                            id, m_mod.Scene.RegionInfo.RegionName);
                    }
                    else
                    {
                        failIfNotOkay = false;
                    }
                }
                else
                {
                    oldState = m_agentsInTransit[id];

                    if (newState == AgentTransferState.Aborting)
                    {
                        transitionOkay = true;
                    }
                    else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
                    {
                        transitionOkay = true;
                    }
                    else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
                    {
                        transitionOkay = true;
                    }
                    else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
                    {
                        transitionOkay = true;
                    }
                    else
                    {
                        if (newState == AgentTransferState.Cancelling &&
                            (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring))
                        {
                            transitionOkay = true;
                        }
                        else
                        {
                            failIfNotOkay = false;
                        }
                    }

                    if (!transitionOkay)
                    {
                        failureMessage
                            = string.Format(
                                  "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
                                  id, oldState, newState, m_mod.Scene.RegionInfo.RegionName);
                    }
                }

                if (transitionOkay)
                {
                    m_agentsInTransit[id] = newState;

//                    m_log.DebugFormat(
//                        "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}",
//                        id, oldState, newState, m_mod.Scene.Name);
                }
                else if (failIfNotOkay)
                {
                    m_log.DebugFormat("{0} UpdateInTransit. Throwing transition failure = {1}", LogHeader, failureMessage);
                    throw new Exception(failureMessage);
                }
//                else
//                {
//                    if (oldState != null)
//                        m_log.DebugFormat(
//                            "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}",
//                            id, oldState, newState, m_mod.Scene.Name);
//                    else
//                        m_log.DebugFormat(
//                            "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit",
//                            id, newState, m_mod.Scene.Name);
//                }
            }

            return(transitionOkay);
        }
        /// <summary>
        /// Updates the state of an agent that is already in transit.
        /// </summary>
        /// <param name='id'></param>
        /// <param name='newState'></param>
        /// <returns></returns>
        /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
        internal bool UpdateInTransit(UUID id, AgentTransferState newState)
        {
            m_log.DebugFormat("{0} UpdateInTransit. agent={1}, newState={2}", LogHeader, id, newState);

            bool transitionOkay = false;

            // We don't want to throw an exception on cancel since this can come it at any time.
            bool failIfNotOkay = true;

            // Should be a failure message if failure is not okay.
            string failureMessage = null;

            AgentTransferState? oldState = null;

            lock (m_agentsInTransit)
            {
                // Illegal to try and update an agent that's not actually in transit.
                if (!m_agentsInTransit.ContainsKey(id))
                {
                    if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting)
                        failureMessage = string.Format(
                                "Agent with ID {0} is not registered as in transit in {1}",
                                id, m_mod.Scene.RegionInfo.RegionName);
                    else
                        failIfNotOkay = false;
                }
                else
                {
                    oldState = m_agentsInTransit[id];

                    if (newState == AgentTransferState.Aborting)
                    {
                        transitionOkay = true;
                    }
                    else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
                    {
                        transitionOkay = true;
                    }
                    else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
                    {
                        transitionOkay = true;
                    }
                    else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
                    {
                        transitionOkay = true;
                    }
                    else
                    {
                        if (newState == AgentTransferState.Cancelling 
                            && (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring))
                        {
                            transitionOkay = true;
                        }
                        else
                        {
                            failIfNotOkay = false;
                        }
                    }

                    if (!transitionOkay)
                        failureMessage 
                            = string.Format(
                                "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
                                id, oldState, newState, m_mod.Scene.RegionInfo.RegionName);
                }

                if (transitionOkay)
                {
                    m_agentsInTransit[id] = newState;

//                    m_log.DebugFormat(
//                        "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}", 
//                        id, oldState, newState, m_mod.Scene.Name);
                }
                else if (failIfNotOkay)
                {
                    m_log.DebugFormat("{0} UpdateInTransit. Throwing transition failure = {1}", LogHeader, failureMessage);
                    throw new Exception(failureMessage);
                }
//                else
//                {
//                    if (oldState != null)
//                        m_log.DebugFormat(
//                            "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}", 
//                            id, oldState, newState, m_mod.Scene.Name);
//                    else
//                        m_log.DebugFormat(
//                            "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit", 
//                            id, newState, m_mod.Scene.Name);
//                }
            }

            return transitionOkay;
        }
        /// <summary>
        /// Updates the state of an agent that is already in transit.
        /// </summary>
        /// <param name='id'></param>
        /// <param name='newState'></param>
        /// <returns></returns>
        /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
        internal void UpdateInTransit(UUID id, AgentTransferState newState)
        {
            lock (m_agentsInTransit)
            {
                // Illegal to try and update an agent that's not actually in transit.
                if (!m_agentsInTransit.ContainsKey(id))
                    throw new Exception(
                        string.Format(
                            "Agent with ID {0} is not registered as in transit in {1}",
                            id, m_mod.Scene.RegionInfo.RegionName));

                AgentTransferState oldState = m_agentsInTransit[id];

                bool transitionOkay = false;

                if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
                    transitionOkay = true;
                else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
                    transitionOkay = true;
                else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
                    transitionOkay = true;

                if (transitionOkay)
                    m_agentsInTransit[id] = newState;
                else
                    throw new Exception(
                        string.Format(
                            "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
                            id, oldState, newState, m_mod.Scene.RegionInfo.RegionName));
            }
        }