From f6f3bd1e4cbc2fb2d411101795eb4fdc86741f85 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 10 May 2016 11:12:37 +0200 Subject: [PATCH] Implement support for limiting the number of concurrent checks fixes #8137 --- doc/6-object-types.md | 8 +++++- lib/checker/checkercomponent.cpp | 48 +++++++++++++++++--------------- lib/checker/checkercomponent.hpp | 1 + lib/checker/checkercomponent.ti | 5 ++++ lib/icinga/checkable-check.cpp | 8 +++--- 5 files changed, 43 insertions(+), 27 deletions(-) diff --git a/doc/6-object-types.md b/doc/6-object-types.md index 54fb0e0e9..1518a62de 100644 --- a/doc/6-object-types.md +++ b/doc/6-object-types.md @@ -189,7 +189,7 @@ Argument array `repeat_key = false`: ## CheckerComponent -The checker component is responsible for scheduling active checks. There are no configurable options. +The checker component is responsible for scheduling active checks. Example: @@ -197,6 +197,12 @@ Example: object CheckerComponent "checker" { } +Configuration Attributes: + + Name |Description + --------------------|---------------- + concurrent\_checks |**Optional.** The maximum number of concurrent checks. Defaults to 512. + ## CheckResultReader Reads Icinga 1.x check results from a directory. This functionality is provided diff --git a/lib/checker/checkercomponent.cpp b/lib/checker/checkercomponent.cpp index 64c37c7e9..6b20cc471 100644 --- a/lib/checker/checkercomponent.cpp +++ b/lib/checker/checkercomponent.cpp @@ -69,6 +69,7 @@ void CheckerComponent::OnConfigLoaded(void) ConfigObject::OnActiveChanged.connect(bind(&CheckerComponent::ObjectHandler, this, _1)); ConfigObject::OnPausedChanged.connect(bind(&CheckerComponent::ObjectHandler, this, _1)); + Checkable::OnNewCheckResult.connect(bind(&CheckerComponent::CheckResultHandler, this, _1)); Checkable::OnNextCheckChanged.connect(bind(&CheckerComponent::NextCheckChangedHandler, this, _1)); } @@ -121,7 +122,7 @@ void CheckerComponent::CheckThreadProc(void) double wait = checkable->GetNextCheck() - Utility::GetTime(); - if (wait > 0) { + if (wait > 0 || m_PendingCheckables.size() >= GetConcurrentChecks()) { /* Wait for the next check. */ m_CV.timed_wait(lock, boost::posix_time::milliseconds(wait * 1000)); @@ -215,27 +216,6 @@ void CheckerComponent::ExecuteCheckHelper(const Checkable::Ptr& checkable) Log(LogCritical, "checker", output); } - - { - boost::mutex::scoped_lock lock(m_Mutex); - - /* remove the object from the list of pending objects; if it's not in the - * list this was a manual (i.e. forced) check and we must not re-add the - * object to the list because it's already there. */ - CheckerComponent::CheckableSet::iterator it; - it = m_PendingCheckables.find(checkable); - if (it != m_PendingCheckables.end()) { - m_PendingCheckables.erase(it); - - if (checkable->IsActive()) - m_IdleCheckables.insert(checkable); - - m_CV.notify_all(); - } - } - - Log(LogDebug, "CheckerComponent") - << "Check finished for object '" << checkable->GetName() << "'"; } void CheckerComponent::ResultTimerHandler(void) @@ -279,6 +259,30 @@ void CheckerComponent::ObjectHandler(const ConfigObject::Ptr& object) } } +void CheckerComponent::CheckResultHandler(const Checkable::Ptr& checkable) +{ + { + boost::mutex::scoped_lock lock(m_Mutex); + + /* remove the object from the list of pending objects; if it's not in the + * list this was a manual (i.e. forced) check and we must not re-add the + * object to the list because it's already there. */ + CheckerComponent::CheckableSet::iterator it; + it = m_PendingCheckables.find(checkable); + if (it != m_PendingCheckables.end()) { + m_PendingCheckables.erase(it); + + if (checkable->IsActive()) + m_IdleCheckables.insert(checkable); + + m_CV.notify_all(); + } + } + + Log(LogDebug, "CheckerComponent") + << "Check finished for object '" << checkable->GetName() << "'"; +} + void CheckerComponent::NextCheckChangedHandler(const Checkable::Ptr& checkable) { boost::mutex::scoped_lock lock(m_Mutex); diff --git a/lib/checker/checkercomponent.hpp b/lib/checker/checkercomponent.hpp index 989668523..f132fe16c 100644 --- a/lib/checker/checkercomponent.hpp +++ b/lib/checker/checkercomponent.hpp @@ -97,6 +97,7 @@ private: void AdjustCheckTimer(void); void ObjectHandler(const ConfigObject::Ptr& object); + void CheckResultHandler(const Checkable::Ptr& checkable); void NextCheckChangedHandler(const Checkable::Ptr& checkable); void RescheduleCheckTimer(void); diff --git a/lib/checker/checkercomponent.ti b/lib/checker/checkercomponent.ti index c35993493..6746b418d 100644 --- a/lib/checker/checkercomponent.ti +++ b/lib/checker/checkercomponent.ti @@ -26,6 +26,11 @@ namespace icinga class CheckerComponent : ConfigObject { + [config] int concurrent_checks { + default {{{ + return 512; + }}} + }; }; } diff --git a/lib/icinga/checkable-check.cpp b/lib/icinga/checkable-check.cpp index 1d5153d57..6e69a8ffa 100644 --- a/lib/icinga/checkable-check.cpp +++ b/lib/icinga/checkable-check.cpp @@ -406,6 +406,10 @@ void Checkable::ExecuteCheck(void) { CONTEXT("Executing check for object '" + GetName() + "'"); + /* keep track of scheduling info in case the check type doesn't provide its own information */ + double scheduled_start = GetNextCheck(); + double before_check = Utility::GetTime(); + UpdateNextCheck(); bool reachable = IsReachable(); @@ -424,10 +428,6 @@ void Checkable::ExecuteCheck(void) SetLastReachable(reachable); } - /* keep track of scheduling info in case the check type doesn't provide its own information */ - double scheduled_start = GetNextCheck(); - double before_check = Utility::GetTime(); - CheckResult::Ptr cr = new CheckResult(); cr->SetScheduleStart(scheduled_start); -- 2.40.0