From abc8d94e5f941df6e594f8a1d3c0cc09e5fac4b6 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sun, 17 Jun 2012 22:46:40 +0200 Subject: [PATCH] Don't run checks for services which have pending checks. --- components/checker/checkercomponent.cpp | 30 ++++++++++++++++++++----- components/checker/checkercomponent.h | 9 ++++++-- icinga/checktask.cpp | 9 ++++++++ icinga/checktask.h | 7 ++++++ icinga/nagioschecktask.cpp | 1 + icinga/service.cpp | 12 ++++++++++ icinga/service.h | 2 ++ 7 files changed, 63 insertions(+), 7 deletions(-) diff --git a/components/checker/checkercomponent.cpp b/components/checker/checkercomponent.cpp index f22ececed..ce36421da 100644 --- a/components/checker/checkercomponent.cpp +++ b/components/checker/checkercomponent.cpp @@ -70,23 +70,23 @@ void CheckerComponent::CheckTimerHandler(void) for (;;) { Service service = m_Services.top(); - if (service.GetNextCheck() > now) + if (service.GetNextCheck() > now || service.HasPendingCheck()) break; + m_Services.pop(); + service.SetPendingCheck(true); + Application::Log(LogInformation, "checker", "Executing service check for '" + service.GetName() + "'"); CheckTask::Ptr task = CheckTask::CreateTask(service); task->Execute(); m_PendingTasks.push_back(task); - m_Services.pop(); service.SetNextCheck(now + service.GetCheckInterval()); m_Services.push(service); } - /* adjust next call time for the check timer */ - Service service = m_Services.top(); - m_CheckTimer->SetInterval(service.GetNextCheck() - now); + AdjustCheckTimer(); } void CheckerComponent::ResultTimerHandler(void) @@ -101,11 +101,31 @@ void CheckerComponent::ResultTimerHandler(void) continue; } + task->GetService().SetPendingCheck(false); + CheckResult result = task->GetResult(); Application::Log(LogInformation, "checker", "Got result! Plugin output: " + result.Output); } m_PendingTasks = unfinishedTasks; + + AdjustCheckTimer(); +} + +void CheckerComponent::AdjustCheckTimer(void) +{ + if (m_Services.size() == 0) + return; + + /* adjust next call time for the check timer */ + Service service = m_Services.top(); + + if (service.HasPendingCheck()) { + m_CheckTimer->Stop(); + } else { + m_CheckTimer->SetInterval(service.GetNextCheck() - time(NULL)); + m_CheckTimer->Start(); + } } void CheckerComponent::AssignServiceRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request) diff --git a/components/checker/checkercomponent.h b/components/checker/checkercomponent.h index 3da7e721e..da924d47c 100644 --- a/components/checker/checkercomponent.h +++ b/components/checker/checkercomponent.h @@ -23,11 +23,14 @@ namespace icinga { -struct ServiceNextCheckGreaterComparer +struct ServiceCheckPriorityLessComparer { public: bool operator()(const Service& a, const Service& b) { + if (a.HasPendingCheck() && !b.HasPendingCheck()) + return true; + return a.GetNextCheck() > b.GetNextCheck(); } }; @@ -41,7 +44,7 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - typedef priority_queue, ServiceNextCheckGreaterComparer> ServiceQueue; + typedef priority_queue, ServiceCheckPriorityLessComparer> ServiceQueue; virtual string GetName(void) const; virtual void Start(void); @@ -58,6 +61,8 @@ private: void CheckTimerHandler(void); void ResultTimerHandler(void); + void AdjustCheckTimer(void); + void AssignServiceRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request); void RevokeServiceRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request); void ClearServicesRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request); diff --git a/icinga/checktask.cpp b/icinga/checktask.cpp index f346053fe..a82ffd7fd 100644 --- a/icinga/checktask.cpp +++ b/icinga/checktask.cpp @@ -4,6 +4,15 @@ using namespace icinga; map CheckTask::m_Types; +CheckTask::CheckTask(const Service& service) + : m_Service(service) +{ } + +Service CheckTask::GetService(void) const +{ + return m_Service; +} + void CheckTask::RegisterType(string type, Factory factory) { m_Types[type] = factory; diff --git a/icinga/checktask.h b/icinga/checktask.h index 091e0c27c..045378c14 100644 --- a/icinga/checktask.h +++ b/icinga/checktask.h @@ -32,6 +32,8 @@ public: typedef function Factory; + Service GetService(void) const; + virtual void Execute(void) = 0; virtual bool IsFinished(void) const = 0; virtual CheckResult GetResult(void) = 0; @@ -39,7 +41,12 @@ public: static void RegisterType(string type, Factory factory); static CheckTask::Ptr CreateTask(const Service& service); +protected: + CheckTask(const Service& service); + private: + Service m_Service; + static map m_Types; }; diff --git a/icinga/nagioschecktask.cpp b/icinga/nagioschecktask.cpp index 60b69efca..4dd6f7d2d 100644 --- a/icinga/nagioschecktask.cpp +++ b/icinga/nagioschecktask.cpp @@ -3,6 +3,7 @@ using namespace icinga; NagiosCheckTask::NagiosCheckTask(const Service& service) + : CheckTask(service) { string checkCommand = service.GetCheckCommand(); m_Command = MacroProcessor::ResolveMacros(checkCommand, service.GetMacros()) + " 2>&1"; diff --git a/icinga/service.cpp b/icinga/service.cpp index e60198673..31405cfae 100644 --- a/icinga/service.cpp +++ b/icinga/service.cpp @@ -86,3 +86,15 @@ string Service::GetChecker(void) const GetConfigObject()->GetTag("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 diff --git a/icinga/service.h b/icinga/service.h index a2680dea4..06dff6641 100644 --- a/icinga/service.h +++ b/icinga/service.h @@ -24,6 +24,8 @@ public: time_t GetNextCheck(void) const; void SetChecker(string checker); string GetChecker(void) const; + void SetPendingCheck(bool pending); + bool HasPendingCheck(void) const; }; } -- 2.40.0