public override bool Execute(NotificationRequest request)
        {
            lock (History)
            {
                var key = GetKey(request);
                AlertHistory alertHistory;

                if (!History.ContainsKey(key))
                {
                    alertHistory = new AlertHistory { Received = DateTime.UtcNow };
                    HandleFirstAlert(request, alertHistory);
                    return true;
                }

                // has count change from last?
                alertHistory = History[key];

                if (!HasNotificationChanged(request, alertHistory))
                {
                    Logger.Debug("ResultCount for Check '{0}' is unchanged, not publishing", request.CheckId);
                    return false;
                }

                HandleStateChange(request, alertHistory);
                return true;
            }
        }
        public override bool Execute(NotificationRequest request)
        {
            lock (History)
            {
                var key = GetKey(request);
                AlertHistory alertHistory;

                if (!History.ContainsKey(key))
                {
                    alertHistory = new AlertHistory
                    {
                        Result = request.Notification.Result,
                        Received = DateTime.UtcNow
                    };

                    var result = request.Notification.Result.GetValueOrDefault(true);

                    if (!result)
                        alertHistory.FailuresSinceLastSuccess++;

                    HandleFirstAlert(request, alertHistory);
                    // only publish if initial failure result
                    return !result;
                }

                // has state change from last?
                alertHistory = History[key];

                if (!HasStateChanged(request, alertHistory))
                {
                    Logger.Debug("State for Check '{0}' is unchanged, not publishing", request.CheckId);
                    return false;
                }

                HandleStateChange(request, alertHistory);
                return true;
            }
        }
        protected override bool HasStateChanged(NotificationRequest request, AlertHistory alertHistory)
        {
            var changed = alertHistory.Result != request.Notification.Result;

            if (changed)
            {
                if (alertHistory.Result.GetValueOrDefault(false))
                {
                    // flipped to success from failure
                    alertHistory.FailuresSinceLastSuccess = 0;
                }

                Logger.Debug("{0} state changed!", request.CheckId);
                return true;
            }

            //  not changed - do we need to consider frequency of our nagging?
            if (alertHistory.Result.HasValue)
            {
                if (alertHistory.Result.Value)
                {
                    // stream of success messages
                    Logger.Debug("{0} result:={1} (success stream)", request.CheckId, alertHistory.Result.Value);
                    return false;
                }

                // stream of failures...check frequency
                alertHistory.FailuresSinceLastSuccess++;
                var minimumMinutesSeparation = FindAlertSeparation(alertHistory.FailuresSinceLastSuccess);
                var minutesDiff = DateTime.UtcNow.Subtract(alertHistory.Received).TotalMinutes;

                Logger.Debug("{0} failures;={1}, separation:={2}, lastdiff:={3}", request.CheckId, alertHistory.FailuresSinceLastSuccess, minimumMinutesSeparation, minutesDiff);
                return (minutesDiff >= minimumMinutesSeparation);
            }

            return true;
        }
 protected virtual bool HasNotificationChanged(NotificationRequest request, AlertHistory alertHistory)
 {
     return !alertHistory.ResultCount.GetValueOrDefault(0).Equals(request.Notification.ResultCount.GetValueOrDefault(0));
 }
 protected virtual void HandleStateChange(NotificationRequest request, AlertHistory alertHistory)
 {
     alertHistory.InjectFrom<LoopValueInjection>(request.Notification);
     alertHistory.Received = DateTime.UtcNow;
 }
 protected virtual void HandleFirstAlert(NotificationRequest request, AlertHistory alertHistory)
 {
     alertHistory.InjectFrom<LoopValueInjection>(request.Notification);
     History.Add(GetKey(request), alertHistory);
 }
 protected virtual bool HasStateChanged(NotificationRequest request, AlertHistory alertHistory)
 {
     return alertHistory.Result != request.Notification.Result;
 }
 protected virtual void HandleStateChange(NotificationRequest request, AlertHistory alertHistory)
 {
     alertHistory.Result = request.Notification.Result;
     alertHistory.Received = DateTime.UtcNow;
 }
 protected virtual void HandleFirstAlert(NotificationRequest request, AlertHistory alertHistory)
 {
     History.Add(GetKey(request), alertHistory);
 }