示例#1
0
        protected abstract void LogToDatabase(string strMessage); // Add other parameters later.

        private void ReadTargetsFromDatabase()
        {
            List <Target>   lstEnabledTargets = new List <Target>();
            MySqlConnection con = DatabaseConnectionProvider.GetMySqlConnection();

            // ThAW TO_DO 2009/08/26 : Use a Select command that only selects enabled targets that are associated with enabled accounts.
            string strCommandText = Target.SelectAllCommand;

            using (MySqlCommand cmd = new MySqlCommand(strCommandText, con))
            {
                using (MySqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Target target = new Target(reader, false);  // Do not close the reader after constructing the object

                        if (target.Enabled)
                        {
                            lstEnabledTargets.Add(target);
                        }
                    }
                }
            }

            foreach (Target target in lstEnabledTargets)
            {
                target.FinishConstruction(con);
                m_pqWaitingTargets.Enqueue(target);
                LogToConsole(string.Format(@"Constructed and enqueued the enabled target named '{0}'", target.Name));
            }
        }
示例#2
0
        public void Run()
        {
            LogToConsole(@"Flare main loop: start");

            lock (this)
            {
                m_eServiceStatus = FlareServiceStatus.Started;
            }

            try
            {
                m_pqWaitingTargets.Clear();
                m_qTargetsReadyForTesting.Clear();

                ReadTargetsFromDatabase();

                MySqlConnection con = DatabaseConnectionProvider.GetMySqlConnection();

                m_lstAllContacts = Contact.GetAllContacts(con);
                m_dictSystemConfigurationEntries = SystemConfigurationEntry.GetDictionary(con);

                if (m_pqWaitingTargets.IsEmpty())
                {
                    LogToConsole(@"Aborting: The priority queue is empty; there are no servers to monitor.");
                    return;
                }

                // The main loop begins here.
                TimeSpan tsOneSecond  = new TimeSpan(0, 0, 1);
                TimeSpan tsLoopPeriod = new TimeSpan(0, 0, 1);
                bool     bLimitNumberOfMainLoopIterations = (NumberOfMainLoopIterations > 0);

                LogToConsole(@"Starting the main loop...");

                for (int nMainLoopIterationNumber = 0;
                     !bLimitNumberOfMainLoopIterations || nMainLoopIterationNumber < NumberOfMainLoopIterations;
                     ++nMainLoopIterationNumber)
                {
                    DateTime dtNow = DateTime.UtcNow;

                    LogToConsole(string.Format(@"It is now {0}.", dtNow.ToLongTimeString()));

                    if (m_pqWaitingTargets.IsEmpty())
                    {
                        LogToConsole(@"The priority queue is empty; sleeping for one second.");
                        System.Threading.Thread.Sleep(tsOneSecond);
                        continue;
                    }

                    Target targetHead = m_pqWaitingTargets.Peek();

                    LogToConsole(string.Format(@"The target at the head of the queue ('{0}') is due to be tested at {1}.",
                                               targetHead.Name, targetHead.DateTimeOfNextMonitor.ToLongTimeString()));

                    if (dtNow < targetHead.DateTimeOfNextMonitor)
                    {
                        TimeSpan tsDifference      = targetHead.DateTimeOfNextMonitor - dtNow;
                        TimeSpan tsTimeSpanToSleep = (tsDifference < tsLoopPeriod) ? tsDifference : tsLoopPeriod;

                        LogToConsole(string.Format(@"It is not yet time to test the target at the head of the queue.  Sleeping for {0} seconds and {1} milliseconds...",
                                                   tsTimeSpanToSleep.Seconds, tsTimeSpanToSleep.Milliseconds));

                        System.Threading.Thread.Sleep(tsTimeSpanToSleep);
                        continue;
                    }

                    lock (m_qTargetsReadyForTesting)
                    {
                        m_qTargetsReadyForTesting.Enqueue(m_pqWaitingTargets.Dequeue());
                    }

#if MULTITHREAD_TARGET_TESTING
                    // Note: There is also a delegate named ParameterizedThreadStart; perhaps it may be useful
                    // in allowing us to pass a TargetInfo object as a parameter, thus avoiding the m_qTargetsReadyForTesting queue.
                    Thread thread = new Thread(new ThreadStart(ThreadMain_TestTarget));

                    thread.Start();
#else
                    ThreadMain_TestTarget();
#endif

                    lock (this)
                    {
                        if (m_eServiceStatus == FlareServiceStatus.StopRequested)
                        {
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogToConsole(string.Format(@"{0} caught: {1}", ex.GetType().FullName, ex.Message));
            }

            lock (this)
            {
                m_eServiceStatus = FlareServiceStatus.Stopped;
            }

            LogToConsole(@"Flare main loop: end");
        }
示例#3
0
        private void ThreadMain_TestTarget()
        {
            LogToConsole(@"**** Thread starting ****");

            Target target = null;

            lock (m_qTargetsReadyForTesting)
            {
                if (m_qTargetsReadyForTesting.Count <= 0)
                {
                    // Throw an exception when we attempt to Dequeue() ?
                    return;
                }

                target = m_qTargetsReadyForTesting.Dequeue();
            }

            LogToConsole(string.Format(@"Testing the target {0} (at {1}).", target.Name, target.URL));

            // In a separate thread:
            // - HTTP Post to the target
            // - Handle any errors (by logging to a database and sending e-mail(s))
            // - Re-enqueue the TargetInfo object while the priority queue is locked.
            TargetLogRecord tlr = null;

            switch (target.MonitorType)
            {
            case MonitorType.eHTTPGet:
                tlr = GetFromTarget(target);
                break;

            case MonitorType.eHTTPPost:
                tlr = PostToTarget(target);
                break;

            case MonitorType.ePing:
                tlr = PingTarget(target);
                break;

                // Default case: Throw an exception?
            }

            if (tlr != null)
            {
                MySqlConnection con = DatabaseConnectionProvider.GetMySqlConnection();

                tlr.Insert(con);
                target.UpdateLastTargetLogID(tlr.LogID, con);

                if (tlr.Status == TargetLogRecordStatus.Fail)
                {
                    // Send an e-mail to each of the target's account's contacts.
                    SendFailureNotificationEmails(target, tlr);
                }
            }

            //target.LastMonitoredAt = DateTime.UtcNow;
            target.UpdateLastMonitoredAt(DateTime.UtcNow, DatabaseConnectionProvider.GetMySqlConnection());
            target.DateTimeOfNextMonitor = target.LastMonitoredAt.Value + target.MonitorIntervalAsTimeSpan;   // or += target.MonitorIntervalAsTimeSpan;
            // Update the target's LastMonitoredAt in the database
            m_pqWaitingTargets.Enqueue(target);

            LogToConsole(string.Format(@"The target {0} has been dequeued, bumped, and re-enqueued.", target.Name));

            LogToConsole(@"**** Thread ending ****");
        }