Exemplo n.º 1
0
        protected virtual void Dry(CancellationTokenPair pair)
        {
            byte unitsToRemove;
            {
                using var lls = LaundryFlags.SpinLock(TimeSpan.FromSeconds(2));
                unitsToRemove = lls.LoadedLaundryItem != LaundryItems.InvalidItem
                    ? lls.LoadedLaundryItem.Dampness
                    : throw new StateLogicErrorException(
                                          "It should not be possible to lack laundry during the wash cycle.");
            }
            byte     unitsToDeduct = unitsToRemove;
            TimeSpan timeRequired  = TimeToDecrementDampnessPerUnit * unitsToRemove;
            double   randomFactor  = RandomNumberSource.Next(1, 11) / 100.0; //introduce randomness factor of 10%, either direction

            Debug.Assert(randomFactor >= 0.0 && randomFactor <= 0.11);
            TimeSpan randomTimeToAddOrSub = timeRequired * randomFactor;

            Debug.Assert(randomTimeToAddOrSub <= timeRequired);
            bool negate = RandomNumberSource.Next(1, 3) == 1;

            randomTimeToAddOrSub = negate ? -randomTimeToAddOrSub : +randomTimeToAddOrSub;
            timeRequired        += randomTimeToAddOrSub;

            Stopwatch sw = null;

            try
            {
                sw = HighPrecisionTimer;
                sw.Restart();
                SimulateWait(pair, timeRequired);
            }
            catch (OperationCanceledException)
            {
                if (sw == null)
                {
                    string log = "For some reason the stopwatch is null.";
                    TerminationHelper.TerminateApplication(log);
                    return;
                }

                TimeSpan elapsed    = sw.Elapsed;
                double   percentage = elapsed >= timeRequired ? 1.0 : elapsed / timeRequired;
                unitsToDeduct = Convert.ToByte(Math.Floor(unitsToRemove * percentage));
                throw;
            }
            finally
            {
                sw?.Reset();
                byte newSetting = (byte)(unitsToRemove - unitsToDeduct);
                Debug.Assert(newSetting <= unitsToRemove);
                using var lls = LaundryFlags.SpinLock(TimeSpan.FromSeconds(2));
                lls.SetDampFactor(newSetting);
                Debug.Assert(lls.LoadedLaundryItem.Dampness <= unitsToRemove);
            }
        }
Exemplo n.º 2
0
        protected virtual void Soak(CancellationTokenPair token)
        {
            Stopwatch sw = null;

            try
            {
                Debug.WriteLine("Beginning Cleanse Soak");
                byte oldDampness;
                byte newDampness;
                sw = HighPrecisionTimer;
                sw.Reset();
                sw.Start();
                {
                    using LockedLaundryStatus lls =
                              LaundryFlags.SpinLock(token.IndividualToken, TimeSpan.FromSeconds(2));
                    var res = lls.SoakLaundry() ??
                              throw new StateLogicErrorException(
                                        "It is supposed to be impossible to start the machine without laundry in it.");
                    oldDampness = res.OldDampness;
                    newDampness = res.NewDampness;
                }

                Debug.Assert(newDampness >= oldDampness);
                int      dampnessUnitsIncrease = newDampness - oldDampness;
                TimeSpan totalTimeRequired     = TimeToIncrementDampnessPerUnit * dampnessUnitsIncrease;
                TimeSpan timeRemaining         = totalTimeRequired - sw.Elapsed;
                if (timeRemaining > TimeSpan.Zero)
                {
                    SimulateWait(token, timeRemaining, "Beginning soak wait", "Ending soak wait");
                }
            }
            catch (StateLogicErrorException ex)
            {
                Console.Error.WriteLineAsync(ex.ToString());
                Environment.Exit(-1);
            }
            catch (TimeoutException)
            {
                Console.Error.WriteAsync(
                    $"Unable to obtain lock in {nameof(Soak)} method of {nameof(WashTask)} task.");
                throw;
            }
            finally
            {
                sw?.Reset();
                Debug.WriteLine("Ending soak.");
            }
        }
Exemplo n.º 3
0
        protected virtual void Cleanse(CancellationTokenPair token)
        {
            byte unitsToRemove;
            {
                using var lls = LaundryFlags.SpinLock(TimeSpan.FromSeconds(2));
                unitsToRemove = lls.LoadedLaundryItem != LaundryItems.InvalidItem
                    ? lls.LoadedLaundryItem.SoiledFactor
                    : throw new StateLogicErrorException(
                                          "It should not be possible to lack laundry during the wash cycle.");
            }
            byte      unitsToDeduct = unitsToRemove;
            TimeSpan  timeRequired  = TimeToRemoveOneUnitOfSoil * unitsToRemove;
            Stopwatch sw            = null;

            try
            {
                sw = HighPrecisionTimer;
                sw.Restart();
                if (timeRequired > TimeSpan.Zero)
                {
                    SimulateWait(token, timeRequired, "Beginning cleanse wait.");
                }
            }
            catch (IndividualOperationCancelledException)
            {
                if (sw == null)
                {
                    string log = "For some reason the stopwatch is null.";
                    TerminationHelper.TerminateApplication(log);
                    return;
                }
                TimeSpan elapsed    = sw.Elapsed;
                double   percentage = elapsed >= timeRequired ? 1.0 : elapsed / timeRequired;
                unitsToDeduct = Convert.ToByte(Math.Floor(unitsToRemove * percentage));
                throw;
            }
            finally
            {
                sw?.Reset();
                byte newSetting = (byte)(unitsToRemove - unitsToDeduct);
                Debug.Assert(newSetting <= unitsToRemove);
                using var lls = LaundryFlags.SpinLock(TimeSpan.FromSeconds(2));
                lls.SetSoilFactor(newSetting);
                Debug.Assert(lls.LoadedLaundryItem.SoiledFactor <= unitsToRemove);
            }
        }
Exemplo n.º 4
0
        protected override TaskResult ExecuteTask(CancellationTokenPair pair)
        {
            bool needToClearError;

            using (var lsfLck = LaundryFlags.Lock(TimeSpan.FromSeconds(2)))
            {
                pair.ThrowIfCancellationRequested();
                needToClearError = lsfLck.ExecuteQuery((in LaundryStatusFlags lsf) =>
                                                       lsf.ErrorRegistrationStatus != ErrorRegistrationStatus.NilStatus);
            }

            if (needToClearError)
            {
                using (var lsfLck = LaundryFlags.Lock(TimeSpan.FromSeconds(2)))
                {
                    lsfLck.ExecuteAction((ref LaundryStatusFlags lsf) =>
                    {
                        bool processing = lsf.ProcessError();
                        if (!processing)
                        {
                            throw new StateLogicErrorException(
                                "Bad state ... error not being handled in correct sequence.");
                        }
                    });
                }

                ClearError(pair);
                pair.ThrowIfCancellationRequested();
                using (var lsfLck = LaundryFlags.Lock(TimeSpan.FromSeconds(2)))
                {
                    lsfLck.ExecuteAction((ref LaundryStatusFlags lsf) =>
                    {
                        bool cleared = lsf.ClearError();
                        if (cleared)
                        {
                            lsf.ResetError();
                        }
                        else
                        {
                            throw new StateLogicErrorException("Ut oh, we couln't fix the error for some reason.");
                        }
                    });
                }
                pair.ThrowIfCancellationRequested();
            }

            TimeSpan simulatedTurnOnCycleTime;

            try
            {
                using var rgen           = RandomNumberSource.RGenVault.SpinLock();
                simulatedTurnOnCycleTime = TimeSpan.FromSeconds(rgen.Value.Next(1, 4));
            }
            catch (TimeoutException ex)
            {
                Console.Error.WriteLineAsync($"Error getting lock on the rgen vault ... exception: [{ex}]");
                simulatedTurnOnCycleTime = TimeSpan.FromSeconds(2);
            }

            SimulateWait(in pair, simulatedTurnOnCycleTime);

            TaskResult ret;

            using var lck = TaskResult.SpinLock(TimeSpan.FromSeconds(2));
            ret           = lck.Value = lck.Value.WithTerminationTaskResultType(TaskResultCode.SuccessResult);
            return(ret);
        }