From 18fb93fc114163e15b841db1cae32622c2daab15 Mon Sep 17 00:00:00 2001
From: "Alexander A. Klimov"
Date: Thu, 22 May 2025 17:11:23 +0200
Subject: [PATCH 1/4] Introduce WaitGroup and StoppableWaitGroup
---
lib/base/CMakeLists.txt | 1 +
lib/base/wait-group.cpp | 38 +++++++++++++++++++++++++++++
lib/base/wait-group.hpp | 54 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 93 insertions(+)
create mode 100644 lib/base/wait-group.cpp
create mode 100644 lib/base/wait-group.hpp
diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt
index 59e83644394..d44254a35e2 100644
--- a/lib/base/CMakeLists.txt
+++ b/lib/base/CMakeLists.txt
@@ -87,6 +87,7 @@ set(base_SOURCES
unixsocket.cpp unixsocket.hpp
utility.cpp utility.hpp
value.cpp value.hpp value-operators.cpp
+ wait-group.cpp wait-group.hpp
win32.hpp
workqueue.cpp workqueue.hpp
)
diff --git a/lib/base/wait-group.cpp b/lib/base/wait-group.cpp
new file mode 100644
index 00000000000..1e1ad00eefc
--- /dev/null
+++ b/lib/base/wait-group.cpp
@@ -0,0 +1,38 @@
+/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
+
+#include "base/wait-group.hpp"
+
+using namespace icinga;
+
+bool StoppableWaitGroup::try_lock_shared()
+{
+ std::unique_lock lock (m_Mutex);
+
+ if (m_Stopped) {
+ return false;
+ }
+
+ ++m_SharedLocks;
+ return true;
+}
+
+void StoppableWaitGroup::unlock_shared()
+{
+ std::unique_lock lock (m_Mutex);
+
+ if (!--m_SharedLocks && m_Stopped) {
+ lock.unlock();
+ m_CV.notify_all();
+ }
+}
+
+/**
+ * Disallow new shared locks, wait for all existing ones.
+ */
+void StoppableWaitGroup::Join()
+{
+ std::unique_lock lock (m_Mutex);
+
+ m_Stopped = true;
+ m_CV.wait(lock, [this] { return !m_SharedLocks; });
+}
diff --git a/lib/base/wait-group.hpp b/lib/base/wait-group.hpp
new file mode 100644
index 00000000000..5b452701167
--- /dev/null
+++ b/lib/base/wait-group.hpp
@@ -0,0 +1,54 @@
+/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
+
+#pragma once
+
+#include "base/object.hpp"
+#include
+#include
+#include
+
+namespace icinga
+{
+
+/**
+ * A synchronization interface that allows concurrent shared locking.
+ *
+ * @ingroup base
+ */
+class WaitGroup : public Object
+{
+public:
+ DECLARE_PTR_TYPEDEFS(WaitGroup);
+
+ virtual bool try_lock_shared() = 0;
+ virtual void unlock_shared() = 0;
+};
+
+/**
+ * A thread-safe wait group that can be stopped to prevent further shared locking.
+ *
+ * @ingroup base
+ */
+class StoppableWaitGroup : public WaitGroup
+{
+public:
+ DECLARE_PTR_TYPEDEFS(StoppableWaitGroup);
+
+ StoppableWaitGroup() = default;
+ StoppableWaitGroup(const StoppableWaitGroup&) = delete;
+ StoppableWaitGroup(StoppableWaitGroup&&) = delete;
+ StoppableWaitGroup& operator=(const StoppableWaitGroup&) = delete;
+ StoppableWaitGroup& operator=(StoppableWaitGroup&&) = delete;
+
+ bool try_lock_shared() override;
+ void unlock_shared() override;
+ void Join();
+
+private:
+ std::mutex m_Mutex;
+ std::condition_variable m_CV;
+ uint_fast32_t m_SharedLocks = 0;
+ bool m_Stopped = false;
+};
+
+}
From c7cca7b460162d713dbf26a1d09219501eb52fa1 Mon Sep 17 00:00:00 2001
From: "Alexander A. Klimov"
Date: Thu, 22 May 2025 17:34:37 +0200
Subject: [PATCH 2/4] Add a StoppableWaitGroup, and join it on #Stop(), to:
ApiListener
CheckerComponent
ExternalCommandListener
LivestatusListener
---
lib/checker/checkercomponent.cpp | 1 +
lib/checker/checkercomponent.hpp | 2 ++
lib/compat/externalcommandlistener.cpp | 2 ++
lib/compat/externalcommandlistener.hpp | 3 +++
lib/livestatus/livestatuslistener.cpp | 1 +
lib/livestatus/livestatuslistener.hpp | 2 ++
lib/remote/apilistener.cpp | 1 +
lib/remote/apilistener.hpp | 2 ++
8 files changed, 14 insertions(+)
diff --git a/lib/checker/checkercomponent.cpp b/lib/checker/checkercomponent.cpp
index 06ebb7bbaf3..db3833963d2 100644
--- a/lib/checker/checkercomponent.cpp
+++ b/lib/checker/checkercomponent.cpp
@@ -81,6 +81,7 @@ void CheckerComponent::Stop(bool runtimeRemoved)
m_CV.notify_all();
}
+ m_WaitGroup->Join();
m_ResultTimer->Stop(true);
m_Thread.join();
diff --git a/lib/checker/checkercomponent.hpp b/lib/checker/checkercomponent.hpp
index 5ace7571c6e..edd3775e585 100644
--- a/lib/checker/checkercomponent.hpp
+++ b/lib/checker/checkercomponent.hpp
@@ -8,6 +8,7 @@
#include "base/configobject.hpp"
#include "base/timer.hpp"
#include "base/utility.hpp"
+#include "base/wait-group.hpp"
#include
#include
#include
@@ -77,6 +78,7 @@ class CheckerComponent final : public ObjectImpl
CheckableSet m_IdleCheckables;
CheckableSet m_PendingCheckables;
+ StoppableWaitGroup::Ptr m_WaitGroup = new StoppableWaitGroup();
Timer::Ptr m_ResultTimer;
void CheckThreadProc();
diff --git a/lib/compat/externalcommandlistener.cpp b/lib/compat/externalcommandlistener.cpp
index b61813beb81..5f5362db6f8 100644
--- a/lib/compat/externalcommandlistener.cpp
+++ b/lib/compat/externalcommandlistener.cpp
@@ -50,6 +50,8 @@ void ExternalCommandListener::Start(bool runtimeCreated)
*/
void ExternalCommandListener::Stop(bool runtimeRemoved)
{
+ m_WaitGroup->Join();
+
Log(LogInformation, "ExternalCommandListener")
<< "'" << GetName() << "' stopped.";
diff --git a/lib/compat/externalcommandlistener.hpp b/lib/compat/externalcommandlistener.hpp
index 895531f782e..62d4f8134ee 100644
--- a/lib/compat/externalcommandlistener.hpp
+++ b/lib/compat/externalcommandlistener.hpp
@@ -5,6 +5,7 @@
#include "compat/externalcommandlistener-ti.hpp"
#include "base/objectlock.hpp"
+#include "base/wait-group.hpp"
#include "base/timer.hpp"
#include "base/utility.hpp"
#include
@@ -29,6 +30,8 @@ class ExternalCommandListener final : public ObjectImpl
void Stop(bool runtimeRemoved) override;
private:
+ StoppableWaitGroup::Ptr m_WaitGroup = new StoppableWaitGroup();
+
#ifndef _WIN32
std::thread m_CommandThread;
diff --git a/lib/livestatus/livestatuslistener.cpp b/lib/livestatus/livestatuslistener.cpp
index e44650bfe58..fe524dcdb3a 100644
--- a/lib/livestatus/livestatuslistener.cpp
+++ b/lib/livestatus/livestatuslistener.cpp
@@ -112,6 +112,7 @@ void LivestatusListener::Stop(bool runtimeRemoved)
<< "'" << GetName() << "' stopped.";
m_Listener->Close();
+ m_WaitGroup->Join();
if (m_Thread.joinable())
m_Thread.join();
diff --git a/lib/livestatus/livestatuslistener.hpp b/lib/livestatus/livestatuslistener.hpp
index dc739f6f1c7..60aaed9306c 100644
--- a/lib/livestatus/livestatuslistener.hpp
+++ b/lib/livestatus/livestatuslistener.hpp
@@ -7,6 +7,7 @@
#include "livestatus/livestatuslistener-ti.hpp"
#include "livestatus/livestatusquery.hpp"
#include "base/socket.hpp"
+#include "base/wait-group.hpp"
#include
using namespace icinga;
@@ -40,6 +41,7 @@ class LivestatusListener final : public ObjectImpl
Socket::Ptr m_Listener;
std::thread m_Thread;
+ StoppableWaitGroup::Ptr m_WaitGroup = new StoppableWaitGroup();
};
}
diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp
index db024c98729..8d5a04e9f6b 100644
--- a/lib/remote/apilistener.cpp
+++ b/lib/remote/apilistener.cpp
@@ -368,6 +368,7 @@ void ApiListener::Stop(bool runtimeDeleted)
m_Timer->Stop(true);
m_RenewOwnCertTimer->Stop(true);
+ m_WaitGroup->Join();
ObjectImpl::Stop(runtimeDeleted);
Log(LogInformation, "ApiListener")
diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp
index eae1fa03e61..3aa4f40db0d 100644
--- a/lib/remote/apilistener.hpp
+++ b/lib/remote/apilistener.hpp
@@ -16,6 +16,7 @@
#include "base/tcpsocket.hpp"
#include "base/tlsstream.hpp"
#include "base/threadpool.hpp"
+#include "base/wait-group.hpp"
#include
#include
#include
@@ -177,6 +178,7 @@ class ApiListener final : public ObjectImpl
Timer::Ptr m_RenewOwnCertTimer;
Endpoint::Ptr m_LocalEndpoint;
+ StoppableWaitGroup::Ptr m_WaitGroup = new StoppableWaitGroup();
static ApiListener::Ptr m_Instance;
static std::atomic m_UpdatedObjectAuthority;
From f4691dd05400465e17d9c465dc022005d9aa4376 Mon Sep 17 00:00:00 2001
From: "Alexander A. Klimov"
Date: Thu, 22 May 2025 17:56:16 +0200
Subject: [PATCH 3/4] Require to pass WaitGroup::Ptr to several methods
Namely:
Checkable#ProcessCheckResult()
ClusterCheckTask::ScriptFunc()
ClusterZoneCheckTask::ScriptFunc()
DummyCheckTask::ScriptFunc()
ExceptionCheckTask::ScriptFunc()
IcingaCheckTask::ScriptFunc()
IfwApiCheckTask::ScriptFunc()
NullCheckTask::ScriptFunc()
PluginCheckTask::ScriptFunc()
RandomCheckTask::ScriptFunc()
SleepCheckTask::ScriptFunc()
IdoCheckTask::ScriptFunc()
IcingadbCheck::ScriptFunc()
CheckCommand#Execute()
Checkable#ExecuteCheck()
ClusterEvents::ExecuteCheckFromQueue()
ExternalCommandProcessor::Process*CheckResult()
ExternalCommandCallback
ExternalCommandProcessor::Execute()
ExternalCommandProcessor::ExecuteFromFile()
ExternalCommandProcessor::ProcessFile()
LivestatusQuery#ExecuteCommandHelper()
LivestatusQuery#Execute()
---
lib/checker/checkercomponent.cpp | 4 +-
lib/compat/externalcommandlistener.cpp | 2 +-
lib/db_ido/idochecktask.cpp | 26 +++---
lib/db_ido/idochecktask.hpp | 2 +-
lib/icinga/apiactions.cpp | 5 +-
lib/icinga/checkable-check.cpp | 14 +--
lib/icinga/checkable-script.cpp | 5 +-
lib/icinga/checkable.hpp | 9 +-
lib/icinga/checkcommand.cpp | 3 +-
lib/icinga/checkcommand.hpp | 1 +
lib/icinga/clusterevents-check.cpp | 2 +-
lib/icinga/clusterevents.cpp | 4 +-
lib/icinga/externalcommandprocessor.cpp | 34 +++++---
lib/icinga/externalcommandprocessor.hpp | 17 ++--
lib/icingadb/icingadbchecktask.cpp | 20 ++---
lib/icingadb/icingadbchecktask.hpp | 2 +-
lib/livestatus/livestatuslistener.cpp | 2 +-
lib/livestatus/livestatusquery.cpp | 8 +-
lib/livestatus/livestatusquery.hpp | 5 +-
lib/methods/clusterchecktask.cpp | 8 +-
lib/methods/clusterchecktask.hpp | 2 +-
lib/methods/clusterzonechecktask.cpp | 12 +--
lib/methods/clusterzonechecktask.hpp | 2 +-
lib/methods/dummychecktask.cpp | 6 +-
lib/methods/dummychecktask.hpp | 2 +-
lib/methods/exceptionchecktask.cpp | 4 +-
lib/methods/exceptionchecktask.hpp | 2 +-
lib/methods/icingachecktask.cpp | 6 +-
lib/methods/icingachecktask.hpp | 2 +-
lib/methods/ifwapichecktask.cpp | 8 +-
lib/methods/ifwapichecktask.hpp | 2 +-
lib/methods/nullchecktask.cpp | 6 +-
lib/methods/nullchecktask.hpp | 2 +-
lib/methods/pluginchecktask.cpp | 13 +--
lib/methods/pluginchecktask.hpp | 6 +-
lib/methods/randomchecktask.cpp | 6 +-
lib/methods/randomchecktask.hpp | 2 +-
lib/methods/sleepchecktask.cpp | 6 +-
lib/methods/sleepchecktask.hpp | 2 +-
lib/remote/apilistener.hpp | 5 ++
test/icinga-checkable-flapping.cpp | 76 ++++++++--------
test/icinga-checkresult.cpp | 110 ++++++++++++------------
test/livestatus.cpp | 2 +-
43 files changed, 243 insertions(+), 214 deletions(-)
diff --git a/lib/checker/checkercomponent.cpp b/lib/checker/checkercomponent.cpp
index db3833963d2..1ebdf5fa12e 100644
--- a/lib/checker/checkercomponent.cpp
+++ b/lib/checker/checkercomponent.cpp
@@ -232,7 +232,7 @@ void CheckerComponent::CheckThreadProc()
void CheckerComponent::ExecuteCheckHelper(const Checkable::Ptr& checkable)
{
try {
- checkable->ExecuteCheck();
+ checkable->ExecuteCheck(m_WaitGroup);
} catch (const std::exception& ex) {
CheckResult::Ptr cr = new CheckResult();
cr->SetState(ServiceUnknown);
@@ -246,7 +246,7 @@ void CheckerComponent::ExecuteCheckHelper(const Checkable::Ptr& checkable)
cr->SetExecutionStart(now);
cr->SetExecutionEnd(now);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, m_WaitGroup);
Log(LogCritical, "checker", output);
}
diff --git a/lib/compat/externalcommandlistener.cpp b/lib/compat/externalcommandlistener.cpp
index 5f5362db6f8..6ca4e3c0969 100644
--- a/lib/compat/externalcommandlistener.cpp
+++ b/lib/compat/externalcommandlistener.cpp
@@ -138,7 +138,7 @@ void ExternalCommandListener::CommandPipeThread(const String& commandPath)
Log(LogInformation, "ExternalCommandListener")
<< "Executing external command: " << command;
- ExternalCommandProcessor::Execute(command);
+ ExternalCommandProcessor::Execute(m_WaitGroup, command);
} catch (const std::exception& ex) {
Log(LogWarning, "ExternalCommandListener")
<< "External command failed: " << DiagnosticInformation(ex, false);
diff --git a/lib/db_ido/idochecktask.cpp b/lib/db_ido/idochecktask.cpp
index 3b5856a6598..d3b93e37b7d 100644
--- a/lib/db_ido/idochecktask.cpp
+++ b/lib/db_ido/idochecktask.cpp
@@ -16,11 +16,11 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, IdoCheck, &IdoCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, IdoCheck, &IdoCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
static void ReportIdoCheck(
- const Checkable::Ptr& checkable, const CheckCommand::Ptr& commandObj,
- const CheckResult::Ptr& cr, String output, ServiceState state = ServiceUnknown
+ const Checkable::Ptr& checkable, const CheckCommand::Ptr& commandObj, const CheckResult::Ptr& cr,
+ const WaitGroup::Ptr& producer, String output, ServiceState state = ServiceUnknown
)
{
if (Checkable::ExecuteCommandProcessFinishedHandler) {
@@ -36,12 +36,12 @@ static void ReportIdoCheck(
} else {
cr->SetState(state);
cr->SetOutput(output);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
}
void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
ServiceState state;
CheckCommand::Ptr commandObj = CheckCommand::ExecuteOverride ? CheckCommand::ExecuteOverride : checkable->GetCheckCommand();
@@ -88,19 +88,19 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
return;
if (idoType.IsEmpty()) {
- ReportIdoCheck(checkable, commandObj, cr, "Attribute 'ido_type' must be set.");
+ ReportIdoCheck(checkable, commandObj, cr, producer, "Attribute 'ido_type' must be set.");
return;
}
if (idoName.IsEmpty()) {
- ReportIdoCheck(checkable, commandObj, cr, "Attribute 'ido_name' must be set.");
+ ReportIdoCheck(checkable, commandObj, cr, producer, "Attribute 'ido_name' must be set.");
return;
}
Type::Ptr type = Type::GetByName(idoType);
if (!type || !DbConnection::TypeInstance->IsAssignableFrom(type)) {
- ReportIdoCheck(checkable, commandObj, cr, "DB IDO type '" + idoType + "' is invalid.");
+ ReportIdoCheck(checkable, commandObj, cr, producer, "DB IDO type '" + idoType + "' is invalid.");
return;
}
@@ -110,14 +110,14 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
DbConnection::Ptr conn = static_pointer_cast(dtype->GetObject(idoName));
if (!conn) {
- ReportIdoCheck(checkable, commandObj, cr, "DB IDO connection '" + idoName + "' does not exist.");
+ ReportIdoCheck(checkable, commandObj, cr, producer, "DB IDO connection '" + idoName + "' does not exist.");
return;
}
double qps = conn->GetQueryCount(60) / 60.0;
if (conn->IsPaused()) {
- ReportIdoCheck(checkable, commandObj, cr, "DB IDO connection is temporarily disabled on this cluster instance.", ServiceOK);
+ ReportIdoCheck(checkable, commandObj, cr, producer, "DB IDO connection is temporarily disabled on this cluster instance.", ServiceOK);
return;
}
@@ -125,10 +125,10 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
if (!conn->GetConnected()) {
if (conn->GetShouldConnect()) {
- ReportIdoCheck(checkable, commandObj, cr, "Could not connect to the database server.", ServiceCritical);
+ ReportIdoCheck(checkable, commandObj, cr, producer, "Could not connect to the database server.", ServiceCritical);
} else {
ReportIdoCheck(
- checkable, commandObj, cr,
+ checkable, commandObj, cr, producer,
"Not currently enabled: Another cluster instance is responsible for the IDO database.", ServiceOK
);
}
@@ -193,5 +193,5 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
{ new PerfdataValue("pending_queries", pendingQueries, false, "", pendingQueriesWarning, pendingQueriesCritical) }
}));
- ReportIdoCheck(checkable, commandObj, cr, msgbuf.str(), state);
+ ReportIdoCheck(checkable, commandObj, cr, producer, msgbuf.str(), state);
}
diff --git a/lib/db_ido/idochecktask.hpp b/lib/db_ido/idochecktask.hpp
index 5868c38671b..1377d676589 100644
--- a/lib/db_ido/idochecktask.hpp
+++ b/lib/db_ido/idochecktask.hpp
@@ -18,7 +18,7 @@ class IdoCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
IdoCheckTask();
diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp
index 0f7e5cff1ae..3a30993fb91 100644
--- a/lib/icinga/apiactions.cpp
+++ b/lib/icinga/apiactions.cpp
@@ -126,7 +126,8 @@ Dictionary::Ptr ApiActions::ProcessCheckResult(const ConfigObject::Ptr& object,
if (params->Contains("ttl"))
cr->SetTtl(HttpUtility::GetLastParameter(params, "ttl"));
- Result result = checkable->ProcessCheckResult(cr);
+ Result result = checkable->ProcessCheckResult(cr, ApiListener::GetInstance()->GetWaitGroup());
+
switch (result) {
case Result::Ok:
return ApiActions::CreateResult(200, "Successfully processed check result for object '" + checkable->GetName() + "'.");
@@ -787,7 +788,7 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, cons
Defer resetCheckCommandOverride([]() {
CheckCommand::ExecuteOverride = nullptr;
});
- cmd->Execute(checkable, cr, execMacros, false);
+ cmd->Execute(checkable, cr, listener->GetWaitGroup(), execMacros, false);
}
} else if (command_type == "EventCommand") {
EventCommand::Ptr cmd = GetSingleObjectByNameUsingPermissions(EventCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser);
diff --git a/lib/icinga/checkable-check.cpp b/lib/icinga/checkable-check.cpp
index 868921dc976..b2b5ca45ee8 100644
--- a/lib/icinga/checkable-check.cpp
+++ b/lib/icinga/checkable-check.cpp
@@ -96,7 +96,7 @@ double Checkable::GetLastCheck() const
return schedule_end;
}
-Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin)
+Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const WaitGroup::Ptr& producer, const MessageOrigin::Ptr& origin)
{
using Result = Checkable::ProcessingResult;
@@ -544,7 +544,7 @@ Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr
return Result::Ok;
}
-void Checkable::ExecuteRemoteCheck(const Dictionary::Ptr& resolvedMacros)
+void Checkable::ExecuteRemoteCheck(const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros)
{
CONTEXT("Executing remote check for object '" << GetName() << "'");
@@ -555,10 +555,10 @@ void Checkable::ExecuteRemoteCheck(const Dictionary::Ptr& resolvedMacros)
cr->SetScheduleStart(scheduled_start);
cr->SetExecutionStart(before_check);
- GetCheckCommand()->Execute(this, cr, resolvedMacros, true);
+ GetCheckCommand()->Execute(this, cr, producer, resolvedMacros, true);
}
-void Checkable::ExecuteCheck()
+void Checkable::ExecuteCheck(const WaitGroup::Ptr& producer)
{
CONTEXT("Executing check for object '" << GetName() << "'");
@@ -599,10 +599,10 @@ void Checkable::ExecuteCheck()
bool local = !endpoint || endpoint == Endpoint::GetLocalEndpoint();
if (local) {
- GetCheckCommand()->Execute(this, cr, nullptr, false);
+ GetCheckCommand()->Execute(this, cr, producer, nullptr, false);
} else {
Dictionary::Ptr macros = new Dictionary();
- GetCheckCommand()->Execute(this, cr, macros, false);
+ GetCheckCommand()->Execute(this, cr, producer, macros, false);
if (endpoint->GetConnected()) {
/* perform check on remote endpoint */
@@ -663,7 +663,7 @@ void Checkable::ExecuteCheck()
cr->SetOutput(output);
- ProcessCheckResult(cr);
+ ProcessCheckResult(cr, producer);
}
{
diff --git a/lib/icinga/checkable-script.cpp b/lib/icinga/checkable-script.cpp
index 764a9f851fd..a455440caf5 100644
--- a/lib/icinga/checkable-script.cpp
+++ b/lib/icinga/checkable-script.cpp
@@ -6,6 +6,7 @@
#include "base/function.hpp"
#include "base/functionwrapper.hpp"
#include "base/scriptframe.hpp"
+#include "remote/apilistener.hpp"
using namespace icinga;
@@ -16,7 +17,9 @@ static void CheckableProcessCheckResult(const CheckResult::Ptr& cr)
REQUIRE_NOT_NULL(self);
if (cr) {
- self->ProcessCheckResult(cr);
+ auto api (ApiListener::GetInstance());
+
+ self->ProcessCheckResult(cr, api ? api->GetWaitGroup() : new StoppableWaitGroup());
}
}
diff --git a/lib/icinga/checkable.hpp b/lib/icinga/checkable.hpp
index da6be56309d..310923ec8f8 100644
--- a/lib/icinga/checkable.hpp
+++ b/lib/icinga/checkable.hpp
@@ -12,6 +12,7 @@
#include "icinga/notification.hpp"
#include "icinga/comment.hpp"
#include "icinga/downtime.hpp"
+#include "base/wait-group.hpp"
#include "remote/endpoint.hpp"
#include "remote/messageorigin.hpp"
#include
@@ -114,15 +115,17 @@ class Checkable : public ObjectImpl
static void UpdateStatistics(const CheckResult::Ptr& cr, CheckableType type);
- void ExecuteRemoteCheck(const Dictionary::Ptr& resolvedMacros = nullptr);
- void ExecuteCheck();
+ void ExecuteRemoteCheck(const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros = nullptr);
+ void ExecuteCheck(const WaitGroup::Ptr& producer);
+
enum class ProcessingResult
{
Ok,
CheckableInactive,
NewerCheckResultPresent,
};
- ProcessingResult ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin = nullptr);
+
+ ProcessingResult ProcessCheckResult(const CheckResult::Ptr& cr, const WaitGroup::Ptr& producer, const MessageOrigin::Ptr& origin = nullptr);
Endpoint::Ptr GetCommandEndpoint() const;
diff --git a/lib/icinga/checkcommand.cpp b/lib/icinga/checkcommand.cpp
index fb8032a199e..e1aed1718b1 100644
--- a/lib/icinga/checkcommand.cpp
+++ b/lib/icinga/checkcommand.cpp
@@ -11,11 +11,12 @@ REGISTER_TYPE(CheckCommand);
thread_local CheckCommand::Ptr CheckCommand::ExecuteOverride;
void CheckCommand::Execute(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
GetExecute()->Invoke({
checkable,
cr,
+ producer,
resolvedMacros,
useResolvedMacros
});
diff --git a/lib/icinga/checkcommand.hpp b/lib/icinga/checkcommand.hpp
index c654cf93e87..1ed3b9ae707 100644
--- a/lib/icinga/checkcommand.hpp
+++ b/lib/icinga/checkcommand.hpp
@@ -23,6 +23,7 @@ class CheckCommand final : public ObjectImpl
static thread_local CheckCommand::Ptr ExecuteOverride;
void Execute(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
+ const WaitGroup::Ptr& producer,
const Dictionary::Ptr& resolvedMacros = nullptr,
bool useResolvedMacros = false);
};
diff --git a/lib/icinga/clusterevents-check.cpp b/lib/icinga/clusterevents-check.cpp
index 40325b4c0e4..205c4c79daa 100644
--- a/lib/icinga/clusterevents-check.cpp
+++ b/lib/icinga/clusterevents-check.cpp
@@ -279,7 +279,7 @@ void ClusterEvents::ExecuteCheckFromQueue(const MessageOrigin::Ptr& origin, cons
if (command_type == "check_command") {
try {
- host->ExecuteRemoteCheck(macros);
+ host->ExecuteRemoteCheck(ApiListener::GetInstance()->GetWaitGroup(), macros);
} catch (const std::exception& ex) {
String output = "Exception occurred while checking '" + host->GetName() + "': " + DiagnosticInformation(ex);
ServiceState state = ServiceUnknown;
diff --git a/lib/icinga/clusterevents.cpp b/lib/icinga/clusterevents.cpp
index b49d2071d0d..a45ac458b64 100644
--- a/lib/icinga/clusterevents.cpp
+++ b/lib/icinga/clusterevents.cpp
@@ -176,9 +176,9 @@ Value ClusterEvents::CheckResultAPIHandler(const MessageOrigin::Ptr& origin, con
}
if (!checkable->IsPaused() && Zone::GetLocalZone() == checkable->GetZone() && endpoint == checkable->GetCommandEndpoint())
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, ApiListener::GetInstance()->GetWaitGroup());
else
- checkable->ProcessCheckResult(cr, origin);
+ checkable->ProcessCheckResult(cr, ApiListener::GetInstance()->GetWaitGroup(), origin);
return Empty;
}
diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp
index 0560947aaac..fbc0432a465 100644
--- a/lib/icinga/externalcommandprocessor.cpp
+++ b/lib/icinga/externalcommandprocessor.cpp
@@ -27,7 +27,7 @@ using namespace icinga;
boost::signals2::signal&)> ExternalCommandProcessor::OnNewExternalCommand;
-void ExternalCommandProcessor::Execute(const String& line)
+void ExternalCommandProcessor::Execute(const WaitGroup::Ptr& producer, const String& line)
{
if (line.IsEmpty())
return;
@@ -54,10 +54,10 @@ void ExternalCommandProcessor::Execute(const String& line)
BOOST_THROW_EXCEPTION(std::invalid_argument("Missing arguments in command: " + line));
std::vector argvExtra(argv.begin() + 1, argv.end());
- Execute(ts, argv[0], argvExtra);
+ Execute(producer, ts, argv[0], argvExtra);
}
-void ExternalCommandProcessor::Execute(double time, const String& command, const std::vector& arguments)
+void ExternalCommandProcessor::Execute(const WaitGroup::Ptr& producer, double time, const String& command, const std::vector& arguments)
{
ExternalCommandInfo eci;
@@ -102,7 +102,7 @@ void ExternalCommandProcessor::Execute(double time, const String& command, const
OnNewExternalCommand(time, command, realArguments);
- eci.Callback(time, realArguments);
+ eci.Callback(producer, time, realArguments);
}
void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandCallback& callback, size_t minArgs, size_t maxArgs)
@@ -115,6 +115,16 @@ void ExternalCommandProcessor::RegisterCommand(const String& command, const Exte
GetCommands()[command] = eci;
}
+void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandCallbackLite& callback, size_t minArgs, size_t maxArgs)
+{
+ RegisterCommand(
+ command,
+ [callback](const WaitGroup::Ptr&, double time, const std::vector& args) { callback(time, args); },
+ minArgs,
+ maxArgs
+ );
+}
+
void ExternalCommandProcessor::RegisterCommands()
{
RegisterCommand("PROCESS_HOST_CHECK_RESULT", &ExternalCommandProcessor::ProcessHostCheckResult, 3);
@@ -237,7 +247,7 @@ void ExternalCommandProcessor::RegisterCommands()
RegisterCommand("DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableServicegroupSvcNotifications, 1);
}
-void ExternalCommandProcessor::ExecuteFromFile(const String& line, std::deque< std::vector >& file_queue)
+void ExternalCommandProcessor::ExecuteFromFile(const WaitGroup::Ptr& producer, const String& line, std::deque>& file_queue)
{
if (line.IsEmpty())
return;
@@ -270,11 +280,11 @@ void ExternalCommandProcessor::ExecuteFromFile(const String& line, std::deque< s
<< "Enqueing external command file " << argvExtra[0];
file_queue.push_back(argvExtra);
} else {
- Execute(ts, argv[0], argvExtra);
+ Execute(producer, ts, argv[0], argvExtra);
}
}
-void ExternalCommandProcessor::ProcessHostCheckResult(double time, const std::vector& arguments)
+void ExternalCommandProcessor::ProcessHostCheckResult(const WaitGroup::Ptr& producer, double time, const std::vector& arguments)
{
Host::Ptr host = Host::GetByName(arguments[0]);
@@ -318,10 +328,10 @@ void ExternalCommandProcessor::ProcessHostCheckResult(double time, const std::ve
Log(LogNotice, "ExternalCommandProcessor")
<< "Processing passive check result for host '" << arguments[0] << "'";
- host->ProcessCheckResult(result);
+ host->ProcessCheckResult(result, producer);
}
-void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const std::vector& arguments)
+void ExternalCommandProcessor::ProcessServiceCheckResult(const WaitGroup::Ptr& producer, double time, const std::vector& arguments)
{
Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
@@ -356,7 +366,7 @@ void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const std:
Log(LogNotice, "ExternalCommandProcessor")
<< "Processing passive check result for service '" << arguments[1] << "'";
- service->ProcessCheckResult(result);
+ service->ProcessCheckResult(result, producer);
}
void ExternalCommandProcessor::ScheduleHostCheck(double, const std::vector& arguments)
@@ -921,7 +931,7 @@ void ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks(double, const st
}
}
-void ExternalCommandProcessor::ProcessFile(double, const std::vector& arguments)
+void ExternalCommandProcessor::ProcessFile(const WaitGroup::Ptr& producer, double, const std::vector& arguments)
{
std::deque< std::vector > file_queue;
file_queue.push_back(arguments);
@@ -946,7 +956,7 @@ void ExternalCommandProcessor::ProcessFile(double, const std::vector& ar
Log(LogNotice, "compat")
<< "Executing external command: " << line;
- ExecuteFromFile(line, file_queue);
+ ExecuteFromFile(producer, line, file_queue);
} catch (const std::exception& ex) {
Log(LogWarning, "ExternalCommandProcessor")
<< "External command failed: " << DiagnosticInformation(ex);
diff --git a/lib/icinga/externalcommandprocessor.hpp b/lib/icinga/externalcommandprocessor.hpp
index a7c5a306873..38db883d245 100644
--- a/lib/icinga/externalcommandprocessor.hpp
+++ b/lib/icinga/externalcommandprocessor.hpp
@@ -5,6 +5,7 @@
#include "icinga/i2-icinga.hpp"
#include "icinga/command.hpp"
+#include "base/wait-group.hpp"
#include "base/string.hpp"
#include
#include
@@ -12,7 +13,8 @@
namespace icinga
{
-typedef std::function& arguments)> ExternalCommandCallback;
+typedef std::function& arguments)> ExternalCommandCallback;
+typedef std::function& arguments)> ExternalCommandCallbackLite;
struct ExternalCommandInfo
{
@@ -23,18 +25,18 @@ struct ExternalCommandInfo
class ExternalCommandProcessor {
public:
- static void Execute(const String& line);
- static void Execute(double time, const String& command, const std::vector& arguments);
+ static void Execute(const WaitGroup::Ptr& producer, const String& line);
+ static void Execute(const WaitGroup::Ptr& producer, double time, const String& command, const std::vector& arguments);
static boost::signals2::signal&)> OnNewExternalCommand;
private:
ExternalCommandProcessor();
- static void ExecuteFromFile(const String& line, std::deque< std::vector >& file_queue);
+ static void ExecuteFromFile(const WaitGroup::Ptr& producer, const String& line, std::deque>& file_queue);
- static void ProcessHostCheckResult(double time, const std::vector& arguments);
- static void ProcessServiceCheckResult(double time, const std::vector& arguments);
+ static void ProcessHostCheckResult(const WaitGroup::Ptr& producer, double time, const std::vector& arguments);
+ static void ProcessServiceCheckResult(const WaitGroup::Ptr& producer, double time, const std::vector& arguments);
static void ScheduleHostCheck(double time, const std::vector& arguments);
static void ScheduleForcedHostCheck(double time, const std::vector& arguments);
static void ScheduleSvcCheck(double time, const std::vector& arguments);
@@ -67,7 +69,7 @@ class ExternalCommandProcessor {
static void DisableServicegroupPassiveSvcChecks(double time, const std::vector& arguments);
static void EnableHostgroupPassiveSvcChecks(double time, const std::vector& arguments);
static void DisableHostgroupPassiveSvcChecks(double time, const std::vector& arguments);
- static void ProcessFile(double time, const std::vector& arguments);
+ static void ProcessFile(const WaitGroup::Ptr& producer, double time, const std::vector& arguments);
static void ScheduleSvcDowntime(double time, const std::vector& arguments);
static void DelSvcDowntime(double time, const std::vector& arguments);
static void ScheduleHostDowntime(double time, const std::vector& arguments);
@@ -157,6 +159,7 @@ class ExternalCommandProcessor {
static void ChangeCustomCommandVarInternal(const Command::Ptr& command, const String& name, const Value& value);
static void RegisterCommand(const String& command, const ExternalCommandCallback& callback, size_t minArgs = 0, size_t maxArgs = UINT_MAX);
+ static void RegisterCommand(const String& command, const ExternalCommandCallbackLite& callback, size_t minArgs = 0, size_t maxArgs = UINT_MAX);
static void RegisterCommands();
static std::mutex& GetMutex();
diff --git a/lib/icingadb/icingadbchecktask.cpp b/lib/icingadb/icingadbchecktask.cpp
index cee93cd3384..54e76e8941e 100644
--- a/lib/icingadb/icingadbchecktask.cpp
+++ b/lib/icingadb/icingadbchecktask.cpp
@@ -13,11 +13,11 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, IcingadbCheck, &IcingadbCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, IcingadbCheck, &IcingadbCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
static void ReportIcingadbCheck(
const Checkable::Ptr& checkable, const CheckCommand::Ptr& commandObj,
- const CheckResult::Ptr& cr, String output, ServiceState state)
+ const CheckResult::Ptr& cr, const WaitGroup::Ptr& producer, String output, ServiceState state)
{
if (Checkable::ExecuteCommandProcessFinishedHandler) {
double now = Utility::GetTime();
@@ -32,7 +32,7 @@ static void ReportIcingadbCheck(
} else {
cr->SetState(state);
cr->SetOutput(output);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
}
@@ -43,7 +43,7 @@ double GetXMessageTs(const Array::Ptr& xMessage)
}
void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
CheckCommand::Ptr commandObj = CheckCommand::ExecuteOverride ? CheckCommand::ExecuteOverride : checkable->GetCheckCommand();
@@ -87,21 +87,21 @@ void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckR
return;
if (icingadbName.IsEmpty()) {
- ReportIcingadbCheck(checkable, commandObj, cr, "Icinga DB UNKNOWN: Attribute 'icingadb_name' must be set.", ServiceUnknown);
+ ReportIcingadbCheck(checkable, commandObj, cr, producer, "Icinga DB UNKNOWN: Attribute 'icingadb_name' must be set.", ServiceUnknown);
return;
}
auto conn (IcingaDB::GetByName(icingadbName));
if (!conn) {
- ReportIcingadbCheck(checkable, commandObj, cr, "Icinga DB UNKNOWN: Icinga DB connection '" + icingadbName + "' does not exist.", ServiceUnknown);
+ ReportIcingadbCheck(checkable, commandObj, cr, producer, "Icinga DB UNKNOWN: Icinga DB connection '" + icingadbName + "' does not exist.", ServiceUnknown);
return;
}
auto redis (conn->GetConnection());
if (!redis || !redis->GetConnected()) {
- ReportIcingadbCheck(checkable, commandObj, cr, "Icinga DB CRITICAL: Not connected to Redis.", ServiceCritical);
+ ReportIcingadbCheck(checkable, commandObj, cr, producer, "Icinga DB CRITICAL: Not connected to Redis.", ServiceCritical);
return;
}
@@ -136,7 +136,7 @@ void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckR
xReadHistoryBacklog = std::move(replies.at(4));
} catch (const std::exception& ex) {
ReportIcingadbCheck(
- checkable, commandObj, cr,
+ checkable, commandObj, cr, producer,
String("Icinga DB CRITICAL: Could not query Redis: ") + ex.what(), ServiceCritical
);
return;
@@ -144,7 +144,7 @@ void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckR
if (!xReadHeartbeat) {
ReportIcingadbCheck(
- checkable, commandObj, cr,
+ checkable, commandObj, cr, producer,
"Icinga DB CRITICAL: The Icinga DB daemon seems to have never run. (Missing heartbeat)",
ServiceCritical
);
@@ -511,5 +511,5 @@ void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckR
}
cr->SetPerformanceData(perfdata);
- ReportIcingadbCheck(checkable, commandObj, cr, msgbuf.str(), state);
+ ReportIcingadbCheck(checkable, commandObj, cr, producer, msgbuf.str(), state);
}
diff --git a/lib/icingadb/icingadbchecktask.hpp b/lib/icingadb/icingadbchecktask.hpp
index ba7d61b1edf..5fffff4f1e3 100644
--- a/lib/icingadb/icingadbchecktask.hpp
+++ b/lib/icingadb/icingadbchecktask.hpp
@@ -18,7 +18,7 @@ class IcingadbCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
IcingadbCheckTask();
diff --git a/lib/livestatus/livestatuslistener.cpp b/lib/livestatus/livestatuslistener.cpp
index fe524dcdb3a..9f48bcdbeba 100644
--- a/lib/livestatus/livestatuslistener.cpp
+++ b/lib/livestatus/livestatuslistener.cpp
@@ -192,7 +192,7 @@ void LivestatusListener::ClientHandler(const Socket::Ptr& client)
break;
LivestatusQuery::Ptr query = new LivestatusQuery(lines, GetCompatLogPath());
- if (!query->Execute(stream))
+ if (!query->Execute(m_WaitGroup, stream))
break;
}
diff --git a/lib/livestatus/livestatusquery.cpp b/lib/livestatus/livestatusquery.cpp
index 0f9b3dac9ce..c152eaf27d5 100644
--- a/lib/livestatus/livestatusquery.cpp
+++ b/lib/livestatus/livestatusquery.cpp
@@ -570,7 +570,7 @@ void LivestatusQuery::ExecuteGetHelper(const Stream::Ptr& stream)
SendResponse(stream, LivestatusErrorOK, result.str());
}
-void LivestatusQuery::ExecuteCommandHelper(const Stream::Ptr& stream)
+void LivestatusQuery::ExecuteCommandHelper(const WaitGroup::Ptr& producer, const Stream::Ptr& stream)
{
{
std::unique_lock lock(l_QueryMutex);
@@ -580,7 +580,7 @@ void LivestatusQuery::ExecuteCommandHelper(const Stream::Ptr& stream)
Log(LogNotice, "LivestatusQuery")
<< "Executing command: " << m_Command;
- ExternalCommandProcessor::Execute(m_Command);
+ ExternalCommandProcessor::Execute(producer, m_Command);
SendResponse(stream, LivestatusErrorOK, "");
}
@@ -621,7 +621,7 @@ void LivestatusQuery::PrintFixed16(const Stream::Ptr& stream, int code, const St
}
}
-bool LivestatusQuery::Execute(const Stream::Ptr& stream)
+bool LivestatusQuery::Execute(const WaitGroup::Ptr& producer, const Stream::Ptr& stream)
{
try {
Log(LogNotice, "LivestatusQuery")
@@ -630,7 +630,7 @@ bool LivestatusQuery::Execute(const Stream::Ptr& stream)
if (m_Verb == "GET")
ExecuteGetHelper(stream);
else if (m_Verb == "COMMAND")
- ExecuteCommandHelper(stream);
+ ExecuteCommandHelper(producer, stream);
else if (m_Verb == "ERROR")
ExecuteErrorHelper(stream);
else
diff --git a/lib/livestatus/livestatusquery.hpp b/lib/livestatus/livestatusquery.hpp
index 910cc162e79..838a9a8f5e8 100644
--- a/lib/livestatus/livestatusquery.hpp
+++ b/lib/livestatus/livestatusquery.hpp
@@ -5,6 +5,7 @@
#include "livestatus/filter.hpp"
#include "livestatus/aggregator.hpp"
+#include "base/wait-group.hpp"
#include "base/object.hpp"
#include "base/array.hpp"
#include "base/stream.hpp"
@@ -33,7 +34,7 @@ class LivestatusQuery final : public Object
LivestatusQuery(const std::vector& lines, const String& compat_log_path);
- bool Execute(const Stream::Ptr& stream);
+ bool Execute(const WaitGroup::Ptr& producer, const Stream::Ptr& stream);
static int GetExternalCommands();
@@ -76,7 +77,7 @@ class LivestatusQuery final : public Object
static String QuoteStringPython(const String& str);
void ExecuteGetHelper(const Stream::Ptr& stream);
- void ExecuteCommandHelper(const Stream::Ptr& stream);
+ void ExecuteCommandHelper(const WaitGroup::Ptr& producer, const Stream::Ptr& stream);
void ExecuteErrorHelper(const Stream::Ptr& stream);
void SendResponse(const Stream::Ptr& stream, int code, const String& data);
diff --git a/lib/methods/clusterchecktask.cpp b/lib/methods/clusterchecktask.cpp
index 6ce28cac440..c629225c39c 100644
--- a/lib/methods/clusterchecktask.cpp
+++ b/lib/methods/clusterchecktask.cpp
@@ -17,10 +17,10 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, ClusterCheck, &ClusterCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, ClusterCheck, &ClusterCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr);
@@ -47,7 +47,7 @@ void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRe
} else {
cr->SetOutput(output);
cr->SetState(ServiceUnknown);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
return;
@@ -92,7 +92,7 @@ void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRe
cr->SetState(state);
cr->SetOutput(output);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
}
diff --git a/lib/methods/clusterchecktask.hpp b/lib/methods/clusterchecktask.hpp
index 16ee8a53c80..39e544c1be5 100644
--- a/lib/methods/clusterchecktask.hpp
+++ b/lib/methods/clusterchecktask.hpp
@@ -17,7 +17,7 @@ class ClusterCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
ClusterCheckTask();
diff --git a/lib/methods/clusterzonechecktask.cpp b/lib/methods/clusterzonechecktask.cpp
index fd52534c308..d7c99138c60 100644
--- a/lib/methods/clusterzonechecktask.cpp
+++ b/lib/methods/clusterzonechecktask.cpp
@@ -12,10 +12,10 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, ClusterZoneCheck, &ClusterZoneCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, ClusterZoneCheck, &ClusterZoneCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr);
@@ -42,7 +42,7 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
cr->SetCommand(commandName);
cr->SetOutput(output);
cr->SetState(state);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
return;
@@ -97,7 +97,7 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
cr->SetCommand(commandName);
cr->SetOutput(output);
cr->SetState(state);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
return;
@@ -123,7 +123,7 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
cr->SetCommand(commandName);
cr->SetOutput(output);
cr->SetState(state);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
return;
}
@@ -213,6 +213,6 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
new PerfdataValue("sum_bytes_received_per_second", bytesReceivedPerSecond)
}));
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
}
diff --git a/lib/methods/clusterzonechecktask.hpp b/lib/methods/clusterzonechecktask.hpp
index 2af442c4c75..2bf3e10656a 100644
--- a/lib/methods/clusterzonechecktask.hpp
+++ b/lib/methods/clusterzonechecktask.hpp
@@ -17,7 +17,7 @@ class ClusterZoneCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
ClusterZoneCheckTask();
diff --git a/lib/methods/dummychecktask.cpp b/lib/methods/dummychecktask.cpp
index 905a022c341..85ef33d9a74 100644
--- a/lib/methods/dummychecktask.cpp
+++ b/lib/methods/dummychecktask.cpp
@@ -13,10 +13,10 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, DummyCheck, &DummyCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, DummyCheck, &DummyCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void DummyCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr);
@@ -70,6 +70,6 @@ void DummyCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResu
cr->SetExecutionEnd(now);
cr->SetCommand(commandName);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
}
diff --git a/lib/methods/dummychecktask.hpp b/lib/methods/dummychecktask.hpp
index 621bbfb9f02..9c32a19ad6e 100644
--- a/lib/methods/dummychecktask.hpp
+++ b/lib/methods/dummychecktask.hpp
@@ -19,7 +19,7 @@ class DummyCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
DummyCheckTask();
diff --git a/lib/methods/exceptionchecktask.cpp b/lib/methods/exceptionchecktask.cpp
index 47707f26ff8..645a751bd8b 100644
--- a/lib/methods/exceptionchecktask.cpp
+++ b/lib/methods/exceptionchecktask.cpp
@@ -12,10 +12,10 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, ExceptionCheck, &ExceptionCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, ExceptionCheck, &ExceptionCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void ExceptionCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr&, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr);
diff --git a/lib/methods/exceptionchecktask.hpp b/lib/methods/exceptionchecktask.hpp
index 09db1045f4a..6d8c8c4e063 100644
--- a/lib/methods/exceptionchecktask.hpp
+++ b/lib/methods/exceptionchecktask.hpp
@@ -18,7 +18,7 @@ class ExceptionCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
ExceptionCheckTask();
diff --git a/lib/methods/icingachecktask.cpp b/lib/methods/icingachecktask.cpp
index d3eae1f33f2..3a8e9fbce93 100644
--- a/lib/methods/icingachecktask.cpp
+++ b/lib/methods/icingachecktask.cpp
@@ -17,10 +17,10 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, IcingaCheck, &IcingaCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, IcingaCheck, &IcingaCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr);
@@ -204,6 +204,6 @@ void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
cr->SetOutput(output);
cr->SetCommand(commandName);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
}
diff --git a/lib/methods/icingachecktask.hpp b/lib/methods/icingachecktask.hpp
index 93def628d76..94e4c6e76a7 100644
--- a/lib/methods/icingachecktask.hpp
+++ b/lib/methods/icingachecktask.hpp
@@ -18,7 +18,7 @@ class IcingaCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
IcingaCheckTask();
diff --git a/lib/methods/ifwapichecktask.cpp b/lib/methods/ifwapichecktask.cpp
index ce48deefc3a..fd3cc21c883 100644
--- a/lib/methods/ifwapichecktask.cpp
+++ b/lib/methods/ifwapichecktask.cpp
@@ -31,7 +31,7 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, IfwApiCheck, &IfwApiCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, IfwApiCheck, &IfwApiCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
static const char* GetUnderstandableError(const std::exception& ex)
{
@@ -194,7 +194,7 @@ static void DoIfwNetIo(
}
void IfwApiCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
namespace asio = boost::asio;
namespace http = boost::beast::http;
@@ -213,7 +213,7 @@ void IfwApiCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
if (!(commandEndpoint->GetCapabilities() & (uint_fast64_t)ApiCapabilities::IfwApiCheckCommand)) {
// Assume "ifw-api-check-command" has been imported into a check command which can also work
// based on "plugin-check-command", delegate respectively and hope for the best
- PluginCheckTask::ScriptFunc(checkable, cr, resolvedMacros, useResolvedMacros);
+ PluginCheckTask::ScriptFunc(checkable, cr, producer, resolvedMacros, useResolvedMacros);
return;
}
}
@@ -275,7 +275,7 @@ void IfwApiCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
callback(cr->GetCommand(), pr);
};
} else {
- reportResult = [checkable, cr]() { checkable->ProcessCheckResult(cr); };
+ reportResult = [checkable, cr, producer] { checkable->ProcessCheckResult(cr, producer); };
}
// Set the default check result state and exit code to unknown for the moment!
diff --git a/lib/methods/ifwapichecktask.hpp b/lib/methods/ifwapichecktask.hpp
index 39327336b0b..0c2b3bac2c8 100644
--- a/lib/methods/ifwapichecktask.hpp
+++ b/lib/methods/ifwapichecktask.hpp
@@ -18,7 +18,7 @@ class IfwApiCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
IfwApiCheckTask();
diff --git a/lib/methods/nullchecktask.cpp b/lib/methods/nullchecktask.cpp
index ee660294ee4..07479c366b2 100644
--- a/lib/methods/nullchecktask.cpp
+++ b/lib/methods/nullchecktask.cpp
@@ -13,10 +13,10 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, NullCheck, &NullCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, NullCheck, &NullCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void NullCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr);
@@ -45,6 +45,6 @@ void NullCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResul
}));
cr->SetState(state);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
}
diff --git a/lib/methods/nullchecktask.hpp b/lib/methods/nullchecktask.hpp
index 954cf8d618b..1b991f13256 100644
--- a/lib/methods/nullchecktask.hpp
+++ b/lib/methods/nullchecktask.hpp
@@ -19,7 +19,7 @@ class NullCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
NullCheckTask();
diff --git a/lib/methods/pluginchecktask.cpp b/lib/methods/pluginchecktask.cpp
index 1a3df810528..f5600bd14a7 100644
--- a/lib/methods/pluginchecktask.cpp
+++ b/lib/methods/pluginchecktask.cpp
@@ -14,10 +14,10 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, PluginCheck, &PluginCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, PluginCheck, &PluginCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr);
@@ -48,8 +48,8 @@ void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
if (Checkable::ExecuteCommandProcessFinishedHandler) {
callback = Checkable::ExecuteCommandProcessFinishedHandler;
} else {
- callback = [checkable, cr](const Value& commandLine, const ProcessResult& pr) {
- ProcessFinishedHandler(checkable, cr, commandLine, pr);
+ callback = [checkable, cr, producer](const Value& commandLine, const ProcessResult& pr) {
+ ProcessFinishedHandler(checkable, cr, producer, commandLine, pr);
};
}
@@ -62,7 +62,8 @@ void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
}
}
-void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Value& commandLine, const ProcessResult& pr)
+void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
+ const WaitGroup::Ptr& producer, const Value& commandLine, const ProcessResult& pr)
{
Checkable::CurrentConcurrentChecks.fetch_sub(1);
Checkable::DecreasePendingChecks();
@@ -93,5 +94,5 @@ void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, co
cr->SetExecutionStart(pr.ExecutionStart);
cr->SetExecutionEnd(pr.ExecutionEnd);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
diff --git a/lib/methods/pluginchecktask.hpp b/lib/methods/pluginchecktask.hpp
index a4fc3a3850d..3491c65f940 100644
--- a/lib/methods/pluginchecktask.hpp
+++ b/lib/methods/pluginchecktask.hpp
@@ -19,13 +19,13 @@ class PluginCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
PluginCheckTask();
- static void ProcessFinishedHandler(const Checkable::Ptr& service,
- const CheckResult::Ptr& cr, const Value& commandLine, const ProcessResult& pr);
+ static void ProcessFinishedHandler(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
+ const WaitGroup::Ptr& producer, const Value& commandLine, const ProcessResult& pr);
};
}
diff --git a/lib/methods/randomchecktask.cpp b/lib/methods/randomchecktask.cpp
index 9b133ef0ee5..ae7547ee515 100644
--- a/lib/methods/randomchecktask.cpp
+++ b/lib/methods/randomchecktask.cpp
@@ -13,10 +13,10 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, RandomCheck, &RandomCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, RandomCheck, &RandomCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void RandomCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr);
@@ -60,6 +60,6 @@ void RandomCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
cr->SetState(state);
cr->SetCommand(commandName);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
}
diff --git a/lib/methods/randomchecktask.hpp b/lib/methods/randomchecktask.hpp
index 00ce663dc9a..82a0c48a7bd 100644
--- a/lib/methods/randomchecktask.hpp
+++ b/lib/methods/randomchecktask.hpp
@@ -18,7 +18,7 @@ class RandomCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
RandomCheckTask();
diff --git a/lib/methods/sleepchecktask.cpp b/lib/methods/sleepchecktask.cpp
index 05ed2675a03..975fde697b1 100644
--- a/lib/methods/sleepchecktask.cpp
+++ b/lib/methods/sleepchecktask.cpp
@@ -9,10 +9,10 @@
using namespace icinga;
-REGISTER_FUNCTION_NONCONST(Internal, SleepCheck, &SleepCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, SleepCheck, &SleepCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void SleepCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{
REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr);
@@ -62,6 +62,6 @@ void SleepCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResu
cr->SetExecutionEnd(now);
cr->SetCommand(commandName);
- checkable->ProcessCheckResult(cr);
+ checkable->ProcessCheckResult(cr, producer);
}
}
diff --git a/lib/methods/sleepchecktask.hpp b/lib/methods/sleepchecktask.hpp
index ed8d59089ab..38019a5bc62 100644
--- a/lib/methods/sleepchecktask.hpp
+++ b/lib/methods/sleepchecktask.hpp
@@ -19,7 +19,7 @@ class SleepCheckTask
{
public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
- const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
+ const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private:
SleepCheckTask();
diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp
index 3aa4f40db0d..d7965508dd3 100644
--- a/lib/remote/apilistener.hpp
+++ b/lib/remote/apilistener.hpp
@@ -152,6 +152,11 @@ class ApiListener final : public ObjectImpl
double GetTlsHandshakeTimeout() const override;
void SetTlsHandshakeTimeout(double value, bool suppress_events, const Value& cookie) override;
+ WaitGroup::Ptr GetWaitGroup() const
+ {
+ return m_WaitGroup;
+ }
+
protected:
void OnConfigLoaded() override;
void OnAllConfigLoaded() override;
diff --git a/test/icinga-checkable-flapping.cpp b/test/icinga-checkable-flapping.cpp
index bc305642590..a63c78fc42d 100644
--- a/test/icinga-checkable-flapping.cpp
+++ b/test/icinga-checkable-flapping.cpp
@@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE(host_not_flapping)
int i = 0;
while (i++ < 10) {
// For some reason, elusive to me, the first check is a state change
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
LogFlapping(host);
LogHostStatus(host);
@@ -107,9 +107,9 @@ BOOST_AUTO_TEST_CASE(host_flapping)
int i = 0;
while (i++ < 25) {
if (i % 2)
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
else
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
LogFlapping(host);
LogHostStatus(host);
@@ -144,18 +144,18 @@ BOOST_AUTO_TEST_CASE(host_flapping_recover)
Utility::SetTime(0);
// A few warning
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
LogFlapping(host);
LogHostStatus(host);
for (int i = 0; i <= 7; i++) {
if (i % 2)
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
else
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
}
LogFlapping(host);
@@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(host_flapping_recover)
BOOST_CHECK(host->GetFlappingCurrent() > 25.0);
BOOST_CHECK(host->IsFlapping());
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
LogFlapping(host);
LogHostStatus(host);
count++;
@@ -203,40 +203,40 @@ BOOST_AUTO_TEST_CASE(host_flapping_docs_example)
Utility::SetTime(0);
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
LogFlapping(host);
LogHostStatus(host);
BOOST_CHECK(host->GetFlappingCurrent() == 39.1);
BOOST_CHECK(host->IsFlapping());
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
LogFlapping(host);
LogHostStatus(host);
diff --git a/test/icinga-checkresult.cpp b/test/icinga-checkresult.cpp
index fdc78915ede..438dee87d7c 100644
--- a/test/icinga-checkresult.cpp
+++ b/test/icinga-checkresult.cpp
@@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(host_1attempt)
CheckNotification(host, false);
std::cout << "First check result (unknown)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
+ host->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(host_1attempt)
CheckNotification(host, true, NotificationProblem);
std::cout << "Second check result (ok)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(host_1attempt)
CheckNotification(host, true, NotificationRecovery);
std::cout << "Third check result (critical)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(host_1attempt)
CheckNotification(host, true, NotificationProblem);
std::cout << "Fourth check result (ok)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, false);
std::cout << "First check result (unknown)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
+ host->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -134,7 +134,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, false);
std::cout << "Second check result (critical)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, true, NotificationProblem);
std::cout << "Third check result (ok)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, true, NotificationRecovery);
std::cout << "Fourth check result (critical)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, false);
std::cout << "Fifth check result (ok)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, false);
std::cout << "First check result (unknown)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
+ host->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, false);
std::cout << "Second check result (critical)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 2);
@@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, false);
std::cout << "Third check result (critical)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, true, NotificationProblem);
std::cout << "Fourth check result (ok)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -223,7 +223,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, true, NotificationRecovery);
std::cout << "Fifth check result (critical)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -231,7 +231,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, false);
std::cout << "Sixth check result (ok)" << std::endl;
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1);
@@ -264,7 +264,7 @@ BOOST_AUTO_TEST_CASE(service_1attempt)
CheckNotification(service, false);
std::cout << "First check result (unknown)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
+ service->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceUnknown);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(service_1attempt)
CheckNotification(service, true, NotificationProblem);
std::cout << "Second check result (ok)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -280,7 +280,7 @@ BOOST_AUTO_TEST_CASE(service_1attempt)
CheckNotification(service, true, NotificationRecovery);
std::cout << "Third check result (critical)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -288,7 +288,7 @@ BOOST_AUTO_TEST_CASE(service_1attempt)
CheckNotification(service, true, NotificationProblem);
std::cout << "Fourth check result (ok)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, false);
std::cout << "First check result (unknown)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
+ service->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceUnknown);
BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, false);
std::cout << "Second check result (critical)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -337,7 +337,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, true, NotificationProblem);
std::cout << "Third check result (ok)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -345,7 +345,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, true, NotificationRecovery);
std::cout << "Fourth check result (critical)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -353,7 +353,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, false);
std::cout << "Fifth check result (ok)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -386,7 +386,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, false);
std::cout << "First check result (unknown)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
+ service->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceUnknown);
BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -394,7 +394,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, false);
std::cout << "Second check result (critical)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 2);
@@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, false);
std::cout << "Third check result (critical)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -410,7 +410,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, true, NotificationProblem);
std::cout << "Fourth check result (ok)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -418,7 +418,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, true, NotificationRecovery);
std::cout << "Fifth check result (critical)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -426,7 +426,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, false);
std::cout << "Sixth check result (ok)" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1);
@@ -470,7 +470,7 @@ BOOST_AUTO_TEST_CASE(host_flapping_notification)
for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
- host->ProcessCheckResult(MakeCheckResult(state));
+ host->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
@@ -481,7 +481,7 @@ BOOST_AUTO_TEST_CASE(host_flapping_notification)
std::cout << "Now calm down..." << std::endl;
for (int i = 0; i < 20; i++) {
- host->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
@@ -527,7 +527,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_notification)
for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
- service->ProcessCheckResult(MakeCheckResult(state));
+ service->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
@@ -540,7 +540,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_notification)
std::cout << "Now calm down..." << std::endl;
for (int i = 0; i < 20; i++) {
- service->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
@@ -585,7 +585,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications)
for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
- service->ProcessCheckResult(MakeCheckResult(state));
+ service->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
@@ -595,11 +595,11 @@ BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications)
//Insert enough check results to get into hard problem state but staying flapping
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
@@ -611,7 +611,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications)
// Calm down
while (service->IsFlapping()) {
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
@@ -641,7 +641,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications)
// Known failure, see #5713
// CheckNotification(service, true, NotificationProblem);
- service->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
// Known failure, see #5713
@@ -686,7 +686,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_into_bad)
for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
- service->ProcessCheckResult(MakeCheckResult(state));
+ service->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
@@ -696,11 +696,11 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_into_bad)
//Insert enough check results to get into hard problem state but staying flapping
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
@@ -712,13 +712,13 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_into_bad)
// Calm down
while (service->IsFlapping()) {
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
CheckNotification(service, true, NotificationFlappingEnd);
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
BOOST_CHECK(service->IsFlapping() == false);
@@ -767,7 +767,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_over_bad_into_ok)
for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
- service->ProcessCheckResult(MakeCheckResult(state));
+ service->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
@@ -777,11 +777,11 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_over_bad_into_ok)
//Insert enough check results to get into hard problem state but staying flapping
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
@@ -793,13 +793,13 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_over_bad_into_ok)
// Calm down
while (service->IsFlapping()) {
- service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
+ service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
}
CheckNotification(service, true, NotificationFlappingEnd);
- service->ProcessCheckResult(MakeCheckResult(ServiceOK));
+ service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval);
BOOST_CHECK(service->IsFlapping() == false);
@@ -894,7 +894,7 @@ BOOST_AUTO_TEST_CASE(suppressed_notification)
for (int i = 0; i < checkAttempts; i++) {
std::cout << " ProcessCheckResult("
<< Service::StateToString(initialState) << ")" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(initialState));
+ service->ProcessCheckResult(MakeCheckResult(initialState), new StoppableWaitGroup());
}
BOOST_CHECK(service->GetState() == initialState);
@@ -972,7 +972,7 @@ BOOST_AUTO_TEST_CASE(suppressed_notification)
// Process check results for the state sequence.
for (ServiceState s : sequence) {
std::cout << " ProcessCheckResult(" << Service::StateToString(s) << ")" << std::endl;
- service->ProcessCheckResult(MakeCheckResult(s));
+ service->ProcessCheckResult(MakeCheckResult(s), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == s);
if (checkAttempts == 1) {
BOOST_CHECK(service->GetStateType() == StateTypeHard);
@@ -1002,7 +1002,7 @@ BOOST_AUTO_TEST_CASE(suppressed_notification)
for (int i = 0; i < checkAttempts && service->GetStateType() == StateTypeSoft; i++) {
std::cout << " ProcessCheckResult(" << Service::StateToString(sequence.back()) << ")"
<< std::endl;
- service->ProcessCheckResult(MakeCheckResult(sequence.back()));
+ service->ProcessCheckResult(MakeCheckResult(sequence.back()), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == sequence.back());
}
}
diff --git a/test/livestatus.cpp b/test/livestatus.cpp
index 6aafa3be3e2..a989eedca99 100644
--- a/test/livestatus.cpp
+++ b/test/livestatus.cpp
@@ -15,7 +15,7 @@ String LivestatusQueryHelper(const std::vector& lines)
std::stringstream stream;
StdioStream::Ptr sstream = new StdioStream(&stream, false);
- query->Execute(sstream);
+ query->Execute(new StoppableWaitGroup(), sstream);
String output;
String result;
From 36743f3100ad5f76dacb6077878ef6b9cfa20999 Mon Sep 17 00:00:00 2001
From: "Alexander A. Klimov"
Date: Tue, 20 May 2025 13:02:26 +0200
Subject: [PATCH 4/4] Checkable#ProcessCheckResult(): discard CR or delay its
producers shutdown
---
lib/icinga/checkable-check.cpp | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/icinga/checkable-check.cpp b/lib/icinga/checkable-check.cpp
index b2b5ca45ee8..2d34ec644d9 100644
--- a/lib/icinga/checkable-check.cpp
+++ b/lib/icinga/checkable-check.cpp
@@ -14,6 +14,7 @@
#include "base/convert.hpp"
#include "base/utility.hpp"
#include "base/context.hpp"
+#include
using namespace icinga;
@@ -101,6 +102,7 @@ Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr
using Result = Checkable::ProcessingResult;
VERIFY(cr);
+ VERIFY(producer);
{
ObjectLock olock(this);
@@ -135,6 +137,14 @@ Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr
cr->SetCheckSource(command_endpoint->GetName());
}
+ std::shared_lock producerLock (*producer, std::try_to_lock);
+
+ if (!producerLock) {
+ // Discard the check result to not delay the current reload.
+ // We'll re-run the check immediately after the reload.
+ return Result::CheckableInactive;
+ }
+
/* agent checks go through the api */
if (command_endpoint && GetExtension("agent_check")) {
ApiListener::Ptr listener = ApiListener::GetInstance();