示例#1
0
        /// <summary>
        /// Handles the Client Status Returned by Log Parsing and then determines what values to feed the DetermineStatus routine.
        /// </summary>
        private void HandleReturnedStatus(SlotStatus returnedStatus, SlotModel slot)
        {
            var statusData = new LegacyClientStatusData
            {
                ClientName                = Settings.Name,
                SlotType                  = slot.UnitInfoModel.UnitInfoData.SlotType,
                UnitRetrievalTime         = slot.UnitInfoModel.UnitInfoData.UnitRetrievalTime,
                UtcOffsetIsZero           = Settings.UtcOffsetIsZero,
                UtcOffset                 = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now),
                ClientTimeOffset          = Settings.ClientTimeOffset,
                TimeOfLastUnitStart       = slot.TimeOfLastUnitStart,
                TimeOfLastFrameProgress   = slot.TimeOfLastFrameProgress,
                CurrentStatus             = slot.Status,
                ReturnedStatus            = returnedStatus,
                FrameTime                 = slot.UnitInfoModel.GetRawTime(Prefs.Get <PpdCalculationType>(Preference.PpdCalculation)),
                BenchmarkAverageFrameTime = GetBenchmarkAverageFrameTimeOrDefault(slot.UnitInfo),
                TimeOfLastFrame           = slot.UnitInfoModel.UnitInfoData.CurrentFrame == null
                                                  ? TimeSpan.Zero
                                                  : slot.UnitInfoModel.UnitInfoData.CurrentFrame.TimeOfFrame,
                UnitStartTimeStamp = slot.UnitInfoModel.UnitInfoData.UnitStartTimeStamp,
                AllowRunningAsync  = Prefs.Get <bool>(Preference.AllowRunningAsync)
            };

            SlotStatus computedStatus = LegacyClientStatus.GetSlotStatus(statusData, Logger);

            // If the returned status is EuePause and current status is not
            if (computedStatus.Equals(SlotStatus.EuePause) && statusData.CurrentStatus.Equals(SlotStatus.EuePause) == false)
            {
                if (Prefs.Get <bool>(Preference.EmailReportingEnabled) &&
                    Prefs.Get <bool>(Preference.ReportEuePause))
                {
                    SendEuePauseEmail(statusData.ClientName);
                }
            }

            // If the returned status is Hung and current status is not
            if (computedStatus.Equals(SlotStatus.Hung) && statusData.CurrentStatus.Equals(SlotStatus.Hung) == false)
            {
                if (Prefs.Get <bool>(Preference.EmailReportingEnabled) &&
                    Prefs.Get <bool>(Preference.ReportHung))
                {
                    SendHungEmail(statusData.ClientName);
                }
            }

            slot.Status = computedStatus;
        }
示例#2
0
        private static SlotStatus DetermineAsyncStatus(LegacyClientStatusData statusData, ILogger logger)
        {
            #region Get Terminal Time
            // Terminal Time - defined as last retrieval time minus twice (7 times for GPU) the current Raw Time per Section.
            // if a new frame has not completed in twice the amount of time it should take to complete we should deem this client Hung.
            DateTime terminalDateTime;

            if (statusData.SlotType.Equals(SlotType.GPU))
            {
                terminalDateTime = statusData.UnitRetrievalTime.Subtract(TimeSpan.FromSeconds(statusData.FrameTime * 7));
            }
            else
            {
                terminalDateTime = statusData.UnitRetrievalTime.Subtract(TimeSpan.FromSeconds(statusData.FrameTime * 2));
            }
            #endregion

            #region Determine Unit Progress Value to Use
            Debug.Assert(statusData.TimeOfLastUnitStart.Equals(DateTime.MinValue) == false);

            DateTime lastProgress = statusData.TimeOfLastUnitStart;
            if (statusData.TimeOfLastFrameProgress > statusData.TimeOfLastUnitStart)
            {
                lastProgress = statusData.TimeOfLastFrameProgress;
            }
            #endregion

            #region Write Verbose Trace
            if (logger.IsDebugEnabled)
            {
                var messages = new List <string>(4);
                messages.Add(String.Format(Constants.ClientNameFormat, statusData.ClientName, "DetermineAsyncStatus"));
                messages.Add(String.Format(" - Retrieval Time (Date) ------- : {0}", statusData.UnitRetrievalTime));
                messages.Add(String.Format(" - Time Of Last Unit Start ----- : {0}", statusData.TimeOfLastUnitStart));
                messages.Add(String.Format(" - Time Of Last Frame Progress - : {0}", statusData.TimeOfLastFrameProgress));
                messages.Add(String.Format(" - Terminal Time (Date) -------- : {0}", terminalDateTime));
                messages.ForEach(logger.Debug);
            }
            #endregion

            if (lastProgress > terminalDateTime)
            {
                return(SlotStatus.RunningAsync);
            }
            // time of last progress is less than terminal time
            return(SlotStatus.Hung);
        }
示例#3
0
        internal static SlotStatus GetSlotStatus(LegacyClientStatusData statusData, ILogger logger)
        {
            switch (statusData.ReturnedStatus)
            {
            case SlotStatus.Running:      // at this point, we should not see Running Status
            case SlotStatus.RunningAsync: // at this point, we should not see RunningAsync Status
            case SlotStatus.RunningNoFrameTimes:
                break;

            case SlotStatus.Unknown:
                logger.ErrorFormat("Unable to Determine Status for Client '{0}'", statusData.ClientName);
                // Update Client Status - don't call Determine Status
                return(statusData.ReturnedStatus);

            case SlotStatus.Offline:
            case SlotStatus.Stopped:
            case SlotStatus.EuePause:
            case SlotStatus.Hung:
            case SlotStatus.Paused:
            case SlotStatus.SendingWorkPacket:
            case SlotStatus.GettingWorkPacket:
                // Update Client Status - don't call Determine Status
                return(statusData.ReturnedStatus);
            }

            // if we have a frame time, use it
            if (statusData.FrameTime > 0)
            {
                SlotStatus status = DetermineStatus(statusData, logger);
                if (status == SlotStatus.Hung && statusData.AllowRunningAsync)
                {
                    return(DetermineAsyncStatus(statusData, logger));
                }
                return(status);
            }

            // no frame time based on the current PPD calculation selection ('LastFrame', 'LastThreeFrames', etc)
            // this section attempts to give DetermineStats values to detect Hung clients before they have a valid
            // frame time - Issue 10
            else
            {
                // if we have no time stamp
                if (statusData.TimeOfLastFrame == TimeSpan.Zero)
                {
                    // use the unit start time
                    statusData.TimeOfLastFrame = statusData.UnitStartTimeStamp;
                }

                statusData.FrameTime = GetBaseFrameTime(statusData.BenchmarkAverageFrameTime, statusData.SlotType);
                if (DetermineStatus(statusData, logger) == SlotStatus.Hung)
                {
                    // Issue 124
                    if (statusData.AllowRunningAsync)
                    {
                        if (DetermineAsyncStatus(statusData, logger) == SlotStatus.Hung)
                        {
                            return(SlotStatus.Hung);
                        }
                        return(statusData.ReturnedStatus);
                    }
                    return(SlotStatus.Hung);
                }
                return(statusData.ReturnedStatus);
            }
        }
示例#4
0
        private static SlotStatus DetermineStatus(LegacyClientStatusData statusData, ILogger logger)
        {
            #region Get Terminal Time
            // Terminal Time - defined as last retrieval time minus twice (7 times for GPU) the current Raw Time per Section.
            // if a new frame has not completed in twice the amount of time it should take to complete we should deem this client Hung.
            DateTime terminalDateTime;

            if (statusData.SlotType.Equals(SlotType.GPU))
            {
                terminalDateTime = statusData.UnitRetrievalTime.Subtract(TimeSpan.FromSeconds(statusData.FrameTime * 7));
            }
            else
            {
                terminalDateTime = statusData.UnitRetrievalTime.Subtract(TimeSpan.FromSeconds(statusData.FrameTime * 2));
            }
            #endregion

            #region Get Last Retrieval Time Date
            DateTime currentFrameDateTime;

            if (statusData.UtcOffsetIsZero)
            {
                // get only the date from the last retrieval time (in universal), we'll add the current time below
                currentFrameDateTime = new DateTime(statusData.UnitRetrievalTime.Date.Ticks, DateTimeKind.Utc);
            }
            else
            {
                // get only the date from the last retrieval time, we'll add the current time below
                currentFrameDateTime = statusData.UnitRetrievalTime.Date;
            }
            #endregion

            #region Apply Frame Time Offset and Set Current Frame Time Date
            TimeSpan offset            = TimeSpan.FromMinutes(statusData.ClientTimeOffset);
            TimeSpan adjustedFrameTime = statusData.TimeOfLastFrame;
            if (statusData.UtcOffsetIsZero == false)
            {
                adjustedFrameTime = adjustedFrameTime.Add(statusData.UtcOffset);
            }
            adjustedFrameTime = adjustedFrameTime.Subtract(offset);

            // client time has already rolled over to the next day. the offset correction has
            // caused the adjusted frame time span to be negetive.  take the that negetive span
            // and add it to a full 24 hours to correct.
            if (adjustedFrameTime < TimeSpan.Zero)
            {
                adjustedFrameTime = TimeSpan.FromDays(1).Add(adjustedFrameTime);
            }

            // the offset correction has caused the frame time span to be greater than 24 hours.
            // subtract the extra day from the adjusted frame time span.
            else if (adjustedFrameTime > TimeSpan.FromDays(1))
            {
                adjustedFrameTime = adjustedFrameTime.Subtract(TimeSpan.FromDays(1));
            }

            // add adjusted Time of Last Frame (TimeSpan) to the DateTime with the correct date
            currentFrameDateTime = currentFrameDateTime.Add(adjustedFrameTime);
            #endregion

            #region Check For Frame from Prior Day (Midnight Rollover on Local Machine)
            bool priorDayAdjust = false;

            // if the current (and adjusted) frame time hours is greater than the last retrieval time hours,
            // and the time difference is greater than an hour, then frame is from the day prior.
            // this should only happen after midnight time on the machine running HFM when the monitored client has
            // not completed a frame since the local machine time rolled over to the next day, otherwise the time
            // stamps between HFM and the client are too far off, a positive offset should be set to correct.
            if (currentFrameDateTime.TimeOfDay.Hours > statusData.UnitRetrievalTime.TimeOfDay.Hours &&
                currentFrameDateTime.TimeOfDay.Subtract(statusData.UnitRetrievalTime.TimeOfDay).Hours > 0)
            {
                priorDayAdjust = true;

                // subtract 1 day from today's date
                currentFrameDateTime = currentFrameDateTime.Subtract(TimeSpan.FromDays(1));
            }
            #endregion

            #region Write Verbose Trace
            if (logger.IsDebugEnabled)
            {
                var messages = new List <string>(10);
                messages.Add(String.Format(Constants.ClientNameFormat, statusData.ClientName, "DetermineStatus"));
                messages.Add(String.Format(" - Retrieval Time (Date) ------- : {0}", statusData.UnitRetrievalTime));
                messages.Add(String.Format(" - Time Of Last Frame (TimeSpan) : {0}", statusData.TimeOfLastFrame));
                messages.Add(String.Format(" - Offset (Minutes) ------------ : {0}", statusData.ClientTimeOffset));
                messages.Add(String.Format(" - Time Of Last Frame (Adjusted) : {0}", adjustedFrameTime));
                messages.Add(String.Format(" - Prior Day Adjustment -------- : {0}", priorDayAdjust));
                messages.Add(String.Format(" - Time Of Last Frame (Date) --- : {0}", currentFrameDateTime));
                messages.Add(String.Format(" - Terminal Time (Date) -------- : {0}", terminalDateTime));
                messages.ForEach(logger.Debug);
            }
            #endregion

            if (currentFrameDateTime > terminalDateTime)
            {
                return(SlotStatus.Running);
            }
            else // current frame is less than terminal time
            {
                return(SlotStatus.Hung);
            }
        }