Beispiel #1
0
        protected void DisposeSubmachines(bool emergencyQuit = false)
        {
            TransportOperationMachine beginPickup  = null;
            TransportOperationMachine endPickup    = null;
            TransportOperationMachine beginDropoff = null;
            TransportOperationMachine endDropoff   = null;

            // Get local references so that the lock isn't held while operating on each machine.
            lock (_subMachineLock)
            {
                beginPickup            = BeginPickupMachine;
                BeginPickupMachine     = null;
                endPickup              = CompletePickupMachine;
                CompletePickupMachine  = null;
                beginDropoff           = BeginDropoffMachine;
                BeginDropoffMachine    = null;
                endDropoff             = CompleteDropoffMachine;
                CompleteDropoffMachine = null;
            }

            DisposeSubmachine(beginPickup, emergencyQuit);
            DisposeSubmachine(endPickup, emergencyQuit);
            DisposeSubmachine(beginDropoff, emergencyQuit);
            DisposeSubmachine(endDropoff, emergencyQuit);
        }
Beispiel #2
0
        private void Retry(TransportOperationMachine startingPoint)
        {
            LogService.Log(LogType.System, LogMessageType.Debug, GetType().Name,
                           string.Format(CultureInfo.InvariantCulture, "Retrying Tray move at '{0}'.", startingPoint.Station.Name));
            NumberOfRetries--;
            // Dispose of the old machines.
            DisposeSubmachines();
            // Create new first machine to execute.
            InitializeSubmachine(startingPoint.Operation);
            // Restart execution of whichever machine died, but don't raise the Started event.
            switch (startingPoint.Operation)
            {
            case TransportOperation.BeginPickup:
                BeginPickupMachine.Execute();
                break;

            case TransportOperation.CompletePickup:
                CompletePickupMachine.Execute();
                break;

            case TransportOperation.BeginDropoff:
                BeginDropoffMachine.Execute();
                break;

            case TransportOperation.CompleteDropoff:
                CompleteDropoffMachine.Execute();
                break;
            }
        }
Beispiel #3
0
        private TransportOperationMachine CreateSubmachine(string name, IActivityMachineBuilder builder, DynamicConfiguration config)
        {
            var submachine = new TransportOperationMachine(name, _dispatcher);

            submachine.Builder       = builder;
            submachine.Configuration = config;
            submachine.Finished     += HandleSubMachineFinished;
            submachine.Interrupted  += HandleSubMachineInterrupted;
            submachine.Expired      += HandleSubMachineExpired;
            submachine.Faulted      += HandleSubMachineFaulted;
            return(submachine);
        }
Beispiel #4
0
 private void DisposeSubmachine(TransportOperationMachine submachine, bool emergencyQuit)
 {
     if (submachine != null)
     {
         submachine.Finished    -= HandleSubMachineFinished;
         submachine.Interrupted -= HandleSubMachineInterrupted;
         submachine.Expired     -= HandleSubMachineExpired;
         submachine.Faulted     -= HandleSubMachineFaulted;
         if (emergencyQuit)
         {
             submachine.EmergencyQuit();
         }
         else
         {
             submachine.Quit();
         }
     }
 }
Beispiel #5
0
        private TransportOperationMachine GetNextOperation(TransportOperationMachine lastMachine, out TransportOperation nextOperation)
        {
            switch (lastMachine.Operation)
            {
            case TransportOperation.BeginPickup:
                // Keep operating if mover was stopped for a tray abort because the tray has to be
                // picked up anyway.
                if (IsStopped && !lastMachine.Tray.IsAborted)
                {
                    break;
                }
                InitializeSubmachine(TransportOperation.CompletePickup);
                nextOperation = TransportOperation.CompletePickup;
                return(CompletePickupMachine);

            case TransportOperation.CompletePickup:
                // Skip the drop-off if this mover was stopped.
                if (IsStopped)
                {
                    break;
                }
                InitializeSubmachine(TransportOperation.BeginDropoff);
                nextOperation = TransportOperation.BeginDropoff;
                return(BeginDropoffMachine);

            case TransportOperation.BeginDropoff:
                // Keep operating if mover was stopped for a tray abort because we don't know
                // how much of the drop-off has run.  CompleteDropoff can recover safely.
                if (IsStopped && !lastMachine.Tray.IsAborted)
                {
                    break;
                }
                InitializeSubmachine(TransportOperation.CompleteDropoff);
                nextOperation = TransportOperation.CompleteDropoff;
                return(CompleteDropoffMachine);
            }
            nextOperation = TransportOperation.BeginPickup;
            return(null);
        }
Beispiel #6
0
        private void HandleSubMachineFinished(object sender, TimeStampedEventArgs e)
        {
            var doneMachine = sender as TransportOperationMachine;
            TransportOperation        nextOperation;
            TransportOperationMachine nextMachine = null;

            // lock here because the submachine references will be accessed.
            lock (_subMachineLock)
            {
                nextMachine = GetNextOperation(doneMachine, out nextOperation);

                if (doneMachine.Operation == TransportOperation.CompleteDropoff)
                {
                    TeardownForFinished();
                }
                else
                {
                    if (nextMachine != null && Transport.State.IsNoneOf(StationState.Stopped, StationState.Disabled) &&
                        !(Transport as IStation).HasErred)
                    {
                        CurrentOperation = nextOperation;
                        OnOperationBeginning(nextOperation);
                        // Last step, execute the next machine.
                        nextMachine.Execute();
                    }
                    else
                    {
                        TeardownForInterruption();
                    }
                }
            }

            if (nextMachine == null && !_isComplete)
            {
                Quit();
                LogService.Log(LogType.System, LogMessageType.Error, GetType().Name,
                               string.Format(CultureInfo.InvariantCulture, "Machine '{0}' failed due to missing {1} sub-machine.", Name, nextOperation.ToString()));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Initialize one of the four transport operation machine types.  Both Pick-up machines have
        /// CanStop turned off because there are no circumstances where a Pick-up operation can be
        /// stopped, even though the TrayMover as a whole can be stopped during pick-up.  Both
        /// Drop-off machines have CanStop turned on initially so that either drop-off operation can
        /// be stopped.  If this TrayMover has already been stopped, then this will also
        /// stop a newly constructed CompleteDropoff machine before returning it.
        /// </summary>
        /// <param name="startingType"></param>
        /// <returns>TransportOperationMachine</returns>
        protected TransportOperationMachine InitializeSubmachine(TransportOperation startingType)
        {
            TransportOperationMachine initialized = null;

            lock (_subMachineLock)
            {
                switch (startingType)
                {
                case TransportOperation.BeginPickup:
                    BeginPickupMachine = CreateSubmachine("BeginTrayPickup", BeginPickupBuilder, _beginPickupConfig);
                    initialized        = BeginPickupMachine;
                    break;

                case TransportOperation.CompletePickup:
                    CompletePickupMachine = CreateSubmachine("CompleteTrayPickup", CompletePickupBuilder, _completePickupConfig);
                    initialized           = CompletePickupMachine;
                    break;

                case TransportOperation.BeginDropoff:
                    BeginDropoffMachine         = CreateSubmachine("BeginTrayDropoff", BeginDropoffBuilder, _beginDropoffConfig);
                    BeginDropoffMachine.CanStop = true;
                    initialized = BeginDropoffMachine;
                    break;

                case TransportOperation.CompleteDropoff:
                    CompleteDropoffMachine         = CreateSubmachine("CompleteTrayDropoff", CompleteDropoffBuilder, _completeDropoffConfig);
                    CompleteDropoffMachine.CanStop = true;
                    // CompleteDropoff needs to know if the mover was already stopped
                    if (IsStopped)
                    {
                        CompleteDropoffMachine.Stop();
                    }
                    initialized = CompleteDropoffMachine;
                    break;
                }
            }
            return(initialized);
        }
Beispiel #8
0
        private void RaiseTransportationException(TransportOperationMachine machineInProgress, string description, Exception innerException = null)
        {
            // If transportation already in error state, just escape.
            if ((Transport as IStation).HasErred)
            {
                return;
            }
            AtlasException ex;

            if (!(machineInProgress.Station as IStation).HasErred && machineInProgress.IsExpired)
            {
                ex = new TrayMoveExpirationException(null, Transport, machineInProgress.Station.Name, machineInProgress.Operation.ToString());
            }
            else if (machineInProgress.HaltOnError)
            {
                // This will give transportation an error and a Busy ResourceAvailability.
                ex = new TrayMoveComponentException(null, innerException, Transport, machineInProgress.Station.Name, machineInProgress.Operation.ToString());
            }
            else
            {
                ex = new TrayMoveInternalException(null, innerException, Transport, machineInProgress.Station.Name, machineInProgress.Operation.ToString(), description);
            }
            ex.Handle();
        }