]> granicus.if.org Git - icinga2/commitdiff
More performance improvements.
authorGunnar Beutner <gunnar.beutner@netways.de>
Tue, 19 Jun 2012 10:23:52 +0000 (12:23 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 19 Jun 2012 13:52:48 +0000 (15:52 +0200)
base/i2-base.h
base/threadpool.cpp
base/threadpool.h
base/timer.cpp
components/checker/checkercomponent.cpp
components/delegation/delegationcomponent.cpp
icinga/nagioschecktask.cpp
icinga/nagioschecktask.h
icinga/service.cpp
icinga/service.h

index c55a2db2889e61a99aca79cd412c8456d2d9cbca..bdfb75729284cea410a9cd768bbcd4934a082e4a 100644 (file)
@@ -127,7 +127,6 @@ using boost::function;
 using boost::thread;
 using boost::thread_group;
 using boost::mutex;
-using boost::unique_lock;
 using boost::condition_variable;
 
 #if defined(__APPLE__) && defined(__MACH__)
index c7eda9f6cc9eecf3aa95e32c39f33016e249c3ff..fb1a3ad72857a0d18120ae467d20a1dc0de50c98 100644 (file)
@@ -12,7 +12,7 @@ ThreadPool::ThreadPool(long numThreads)
 ThreadPool::~ThreadPool(void)
 {
        {
-               unique_lock<mutex> lock(m_Lock);
+               mutex::scoped_lock lock(m_Lock);
 
                m_Tasks.clear();
 
@@ -24,24 +24,47 @@ ThreadPool::~ThreadPool(void)
        m_Threads.join_all();
 }
 
-void ThreadPool::EnqueueTasks(const vector<Task>& tasks)
+void ThreadPool::EnqueueTasks(list<ThreadPoolTask::Ptr>& tasks)
 {
-       unique_lock<mutex> lock(m_Lock);
+       {
+               mutex::scoped_lock lock(m_Lock);
+               m_Tasks.splice(m_Tasks.end(), tasks, tasks.begin(), tasks.end());
+       }
 
-       std::copy(tasks.begin(), tasks.end(), std::back_inserter(m_Tasks));
        m_CV.notify_all();
 }
 
-void ThreadPool::EnqueueTask(Task task)
+void ThreadPool::EnqueueTask(const ThreadPoolTask::Ptr& task)
 {
-       unique_lock<mutex> lock(m_Lock);
-       m_Tasks.push_back(task);
+       {
+               mutex::scoped_lock lock(m_Lock);
+               m_Tasks.push_back(task);
+       }
+
        m_CV.notify_one();
 }
 
+
+ThreadPoolTask::Ptr ThreadPool::DequeueTask(void)
+{
+       mutex::scoped_lock lock(m_Lock);
+
+       while (m_Tasks.empty()) {
+               if (!m_Alive)
+                       return ThreadPoolTask::Ptr();
+
+               m_CV.wait(lock);
+       }
+
+       ThreadPoolTask::Ptr task = m_Tasks.front();
+       m_Tasks.pop_front();
+
+       return task;
+}
+
 void ThreadPool::WaitForTasks(void)
 {
-       unique_lock<mutex> lock(m_Lock);
+       mutex::scoped_lock lock(m_Lock);
 
        /* wait for all pending tasks */
        while (!m_Tasks.empty())
@@ -51,23 +74,12 @@ void ThreadPool::WaitForTasks(void)
 void ThreadPool::WorkerThreadProc(void)
 {
        while (true) {
-               Task task;
+               ThreadPoolTask::Ptr task = DequeueTask();
 
-               {
-                       unique_lock<mutex> lock(m_Lock);
+               if (!task)
+                       break;
 
-                       while (m_Tasks.empty()) {
-                               if (!m_Alive)
-                                       return;
-
-                               m_CV.wait(lock);
-                       }
-
-                       task = m_Tasks.front();
-                       m_Tasks.pop_front();
-               }
-
-               task();
+               task->Execute();
        }
 }
 
@@ -80,3 +92,4 @@ ThreadPool::Ptr ThreadPool::GetDefaultPool(void)
 
        return threadPool;
 }
+
index 3d8bc2947454b405c0c3eebb7acd07dc33403f0c..7c905b09a72044d3fbe1e7aab43fc13212332a6f 100644 (file)
@@ -4,32 +4,39 @@
 namespace icinga
 {
 
+struct ThreadPoolTask
+{
+       typedef shared_ptr<ThreadPoolTask> Ptr;
+       typedef weak_ptr<ThreadPoolTask> WeakPtr;
+
+       virtual void Execute(void) = 0;
+};
+
 class I2_BASE_API ThreadPool : public Object
 {
 public:
        typedef shared_ptr<ThreadPool> Ptr;
        typedef weak_ptr<ThreadPool> WeakPtr;
 
-       typedef function<void()> Task;
-
-       ThreadPool(long numThreads = 16);
+       ThreadPool(long numThreads = 128);
        ~ThreadPool(void);
 
        static ThreadPool::Ptr GetDefaultPool(void);
 
-       void EnqueueTasks(const vector<Task>& tasks);
-       void EnqueueTask(Task task);
+       void EnqueueTasks(list<ThreadPoolTask::Ptr>& tasks);
+       void EnqueueTask(const ThreadPoolTask::Ptr& task);
        void WaitForTasks(void);
 
 private:
-       mutex m_Lock;
+       mutable mutex m_Lock;
        condition_variable m_CV;
 
-       deque<Task> m_Tasks;
+       list<ThreadPoolTask::Ptr> m_Tasks;
 
        thread_group m_Threads;
        bool m_Alive;
 
+       ThreadPoolTask::Ptr DequeueTask(void);
        void WorkerThreadProc(void);
 };
 
index 90ff47dd0831cbf88b4ebc88b049d5a9dbfc2788..0f003350eb661d2238dd2eb8725aa1f30240de15 100644 (file)
@@ -87,7 +87,7 @@ void Timer::CallExpiredTimers(void)
 
                if (timer->m_Next <= now) {
                        timer->Call();
-                       timer->Reschedule(now + timer->GetInterval());
+                       timer->Reschedule(time(NULL) + timer->GetInterval());
                }
        }
 }
index 03b970ba9cd00b87b18c8d6cd68dfc2a4e321b05..c0cfa3ac86b4cd4b2afb9e058e7c94bc5817b3dd 100644 (file)
@@ -39,7 +39,7 @@ void CheckerComponent::Start(void)
        GetEndpointManager()->RegisterEndpoint(m_CheckerEndpoint);
 
        m_CheckTimer = boost::make_shared<Timer>();
-       m_CheckTimer->SetInterval(10);
+       m_CheckTimer->SetInterval(5);
        m_CheckTimer->OnTimerExpired.connect(boost::bind(&CheckerComponent::CheckTimerHandler, this));
        m_CheckTimer->Start();
 
@@ -88,8 +88,6 @@ void CheckerComponent::CheckTimerHandler(void)
 
        CheckTask::FlushQueue();
 
-       AdjustCheckTimer();
-
        stringstream msgbuf;
        msgbuf << "CheckTimerHandler: created " << tasks << " tasks";
        Application::Log(LogDebug, "checker", msgbuf.str());
@@ -102,7 +100,7 @@ void CheckerComponent::ResultTimerHandler(void)
        time_t now;
        time(&now);
 
-       long results = 0;
+       long latency = 0, results = 0;
 
        vector<CheckTask::Ptr> finishedTasks = CheckTask::GetFinishedTasks();
 
@@ -114,6 +112,7 @@ void CheckerComponent::ResultTimerHandler(void)
                CheckResult result = task->GetResult();
 //             Application::Log(LogInformation, "checker", "Got result! Plugin output: " + result.Output);
 
+               latency += result.EndTime - result.StartTime;
                results++;
 
                service.SetNextCheck(now + service.GetCheckInterval());
@@ -121,20 +120,8 @@ void CheckerComponent::ResultTimerHandler(void)
        }
 
        stringstream msgbuf;
-       msgbuf << "ResultTimerHandler: " << results << " results";
+       msgbuf << "ResultTimerHandler: " << results << " results; avg. latency: " << latency / (results ? results : 1);
        Application::Log(LogDebug, "checker", msgbuf.str());
-
-       AdjustCheckTimer();
-}
-
-void CheckerComponent::AdjustCheckTimer(void)
-{
-       if (m_Services.empty())
-               return;
-
-       /* adjust next call time for the check timer */
-       Service service = m_Services.top();
-       m_CheckTimer->Reschedule(service.GetNextCheck());
 }
 
 void CheckerComponent::AssignServiceRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request)
index f2a9de172c5b8325f7da655377abed40826c1db1..f52a4806091dd5ec8a2947232cb7edeb9966e45d 100644 (file)
@@ -109,6 +109,8 @@ void DelegationComponent::DelegationTimerHandler(void)
 
                AssignService(service);
        }
+
+       m_DelegationTimer->Stop();
 }
 
 EXPORT_COMPONENT(delegation, DelegationComponent);
index c941dc576bfb346c239868396d50ab444ff6365c..1b67bc17e3388bc2fe7ea931952315f876d8944f 100644 (file)
@@ -2,7 +2,7 @@
 
 using namespace icinga;
 
-vector<ThreadPool::Task> NagiosCheckTask::m_QueuedTasks;
+list<ThreadPoolTask::Ptr> NagiosCheckTask::m_QueuedTasks;
 
 boost::mutex NagiosCheckTask::m_FinishedTasksMutex;
 vector<CheckTask::Ptr> NagiosCheckTask::m_FinishedTasks;
@@ -16,7 +16,9 @@ NagiosCheckTask::NagiosCheckTask(const Service& service)
 
 void NagiosCheckTask::Enqueue(void)
 {
-       m_QueuedTasks.push_back(bind(&NagiosCheckTask::Execute, static_cast<NagiosCheckTask::Ptr>(GetSelf())));
+       time(&m_Result.StartTime);
+       m_QueuedTasks.push_back(static_pointer_cast<ThreadPoolTask>(static_cast<NagiosCheckTask::Ptr>(GetSelf())));
+//     m_QueuedTasks.push_back(new ThreadPool:Task(bind(&NagiosCheckTask::Execute, static_cast<NagiosCheckTask::Ptr>(GetSelf()))));
 }
 
 void NagiosCheckTask::FlushQueue(void)
@@ -27,7 +29,7 @@ void NagiosCheckTask::FlushQueue(void)
 
 void NagiosCheckTask::GetFinishedTasks(vector<CheckTask::Ptr>& tasks)
 {
-       unique_lock<mutex> lock(m_FinishedTasksMutex);
+       mutex::scoped_lock lock(m_FinishedTasksMutex);
        std::copy(m_FinishedTasks.begin(), m_FinishedTasks.end(), back_inserter(tasks));
        m_FinishedTasks.clear();
 }
@@ -39,28 +41,25 @@ CheckResult NagiosCheckTask::GetResult(void)
 
 void NagiosCheckTask::Execute(void)
 {
-       m_Result = RunCheck();
+       RunCheck();
 
        {
-               unique_lock<mutex> lock(m_FinishedTasksMutex);
+               mutex::scoped_lock lock(m_FinishedTasksMutex);
                m_FinishedTasks.push_back(GetSelf());
        }
 }
 
-CheckResult NagiosCheckTask::RunCheck(void) const
+void NagiosCheckTask::RunCheck(void)
 {
-       CheckResult cr;
        FILE *fp;
 
-       time(&cr.StartTime);
-
 #ifdef _MSC_VER
        fp = _popen(m_Command.c_str(), "r");
 #else /* _MSC_VER */
        fp = popen(m_Command.c_str(), "r");
 #endif /* _MSC_VER */
 
-       stringstream outputbuf;
+//     ostringstream outputbuf;
 
        while (!feof(fp)) {
                char buffer[128];
@@ -69,11 +68,11 @@ CheckResult NagiosCheckTask::RunCheck(void) const
                if (read == 0)
                        break;
 
-               outputbuf << string(buffer, buffer + read);
+//             outputbuf.write(buffer, read);
        }
 
-       cr.Output = outputbuf.str();
-       boost::algorithm::trim(cr.Output);
+//     m_Result.Output = outputbuf.str();
+//     boost::algorithm::trim(m_Result.Output);
 
        int status, exitcode;
 #ifdef _MSC_VER
@@ -91,28 +90,26 @@ CheckResult NagiosCheckTask::RunCheck(void) const
 
                switch (exitcode) {
                        case 0:
-                               cr.State = StateOK;
+                               m_Result.State = StateOK;
                                break;
                        case 1:
-                               cr.State = StateWarning;
+                               m_Result.State = StateWarning;
                                break;
                        case 2:
-                               cr.State = StateCritical;
+                               m_Result.State = StateCritical;
                                break;
                        default:
-                               cr.State = StateUnknown;
+                               m_Result.State = StateUnknown;
                                break;
                }
 #ifndef _MSC_VER
        } else if (WIFSIGNALED(status)) {
-               cr.Output = "Process was terminated by signal " + WTERMSIG(status);
-               cr.State = StateUnknown;
+               m_Result.Output = "Process was terminated by signal " + WTERMSIG(status);
+               m_Result.State = StateUnknown;
        }
 #endif /* _MSC_VER */
 
-       time(&cr.EndTime);
-
-       return cr;
+       time(&m_Result.EndTime);
 }
 
 CheckTask::Ptr NagiosCheckTask::CreateTask(const Service& service)
index 89671621757eb62356a3b99279c024d82183af4e..e835b505b56c4b37c9589c8303d116c39cdad308 100644 (file)
@@ -4,7 +4,7 @@
 namespace icinga
 {
 
-class I2_ICINGA_API NagiosCheckTask : public CheckTask
+class I2_ICINGA_API NagiosCheckTask : public CheckTask, public ThreadPoolTask
 {
 public:
        typedef shared_ptr<NagiosCheckTask> Ptr;
@@ -23,13 +23,13 @@ private:
        string m_Command;
        CheckResult m_Result;
 
-       static vector<ThreadPool::Task> m_QueuedTasks;
+       static list<ThreadPoolTask::Ptr> m_QueuedTasks;
 
        static boost::mutex m_FinishedTasksMutex;
        static vector<CheckTask::Ptr> m_FinishedTasks;
 
-       void Execute(void);
-       CheckResult RunCheck(void) const;
+       virtual void Execute(void);
+       void RunCheck(void);
 };
 
 }
index 8e1394ce1f1a456966f7614e6d6a1703bd906ef0..3e29a7909bfd2d6de6b1c2174008fa23d12d5cee 100644 (file)
@@ -69,42 +69,26 @@ long Service::GetRetryInterval(void) const
 
 void Service::SetNextCheck(time_t nextCheck)
 {
-       GetConfigObject()->SetTag("next_check", static_cast<long>(nextCheck));
+       m_NextCheck = nextCheck;
 }
 
 time_t Service::GetNextCheck(void)
 {
-       long value = -1;
-       GetConfigObject()->GetTag("next_check", &value);
+       if (m_NextCheck == -1)
+               m_NextCheck = time(NULL) + rand() % GetCheckInterval();
 
-       if (value == -1) {
-               value = time(NULL) + rand() % GetCheckInterval();
-               SetNextCheck(value);
-       }
-
-       return value;
+       return m_NextCheck;
 }
 
 void Service::SetChecker(string checker)
 {
-       GetConfigObject()->SetTag("checker", checker);
+       GetConfigObject()->SetProperty("checker", checker);
 }
 
 string Service::GetChecker(void) const
 {
        string value;
-       GetConfigObject()->GetTag("checker", &value);
+       GetConfigObject()->GetProperty("checker", &value);
        return value;
 }
 
-void Service::SetPendingCheck(bool pending)
-{
-       GetConfigObject()->SetTag("pendingCheck", pending);
-}
-
-bool Service::HasPendingCheck(void) const
-{
-       bool value = false;
-       GetConfigObject()->GetTag("pendingCheck", &value);
-       return value;
-}
\ No newline at end of file
index 04f583788d45f887007c928d159dc10888885179..ec063752a50fefe3ed1b846412ebd92d284268ab 100644 (file)
@@ -8,7 +8,7 @@ class I2_ICINGA_API Service : public ConfigObjectAdapter
 {
 public:
        Service(const ConfigObject::Ptr& configObject)
-               : ConfigObjectAdapter(configObject)
+               : ConfigObjectAdapter(configObject), m_NextCheck(-1)
        { }
 
        string GetDisplayName(void) const;
@@ -24,8 +24,9 @@ public:
        time_t GetNextCheck(void);
        void SetChecker(string checker);
        string GetChecker(void) const;
-       void SetPendingCheck(bool pending);
-       bool HasPendingCheck(void) const;
+
+private:
+       time_t m_NextCheck;
 };
 
 }