Checkable#ProcessCheckResult(): discard CR or delay its producers shutdown

This commit is contained in:
Alexander A. Klimov 2025-04-02 10:55:43 +02:00
parent 84cb9d8371
commit 23c2365115
5 changed files with 54 additions and 5 deletions

View File

@ -14,6 +14,7 @@
#include "base/convert.hpp"
#include "base/utility.hpp"
#include "base/context.hpp"
#include <shared_mutex>
using namespace icinga;
@ -94,7 +95,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 CheckResultProducer::Ptr& producer, const MessageOrigin::Ptr& origin)
{
using Result = Checkable::ProcessingResult;
@ -106,6 +107,9 @@ Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr
if (!cr)
return Result::NoCheckResult;
if (!producer)
return Result::NoCheckResult;
double now = Utility::GetTime();
if (cr->GetScheduleStart() == 0)
@ -134,6 +138,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();

View File

@ -9,18 +9,18 @@
using namespace icinga;
static void CheckableProcessCheckResult(const CheckResult::Ptr& cr)
static void CheckableProcessCheckResult(const CheckResult::Ptr& cr, const CheckResultProducer::Ptr& producer)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Checkable::Ptr self = vframe->Self;
REQUIRE_NOT_NULL(self);
self->ProcessCheckResult(cr);
self->ProcessCheckResult(cr, producer);
}
Object::Ptr Checkable::GetPrototype()
{
static Dictionary::Ptr prototype = new Dictionary({
{ "process_check_result", new Function("Checkable#process_check_result", CheckableProcessCheckResult, { "cr" }, false) }
{ "process_check_result", new Function("Checkable#process_check_result", CheckableProcessCheckResult, { "cr", "producer" }, false) }
});
return prototype;

View File

@ -12,6 +12,7 @@
#include "icinga/notification.hpp"
#include "icinga/comment.hpp"
#include "icinga/downtime.hpp"
#include "remote/crproducer.hpp"
#include "remote/endpoint.hpp"
#include "remote/messageorigin.hpp"
#include <condition_variable>
@ -119,7 +120,8 @@ public:
CheckableInactive,
NewerCheckResultPresent,
};
ProcessingResult ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin = nullptr);
ProcessingResult ProcessCheckResult(const CheckResult::Ptr& cr, const CheckResultProducer::Ptr& producer, const MessageOrigin::Ptr& origin = nullptr);
Endpoint::Ptr GetCommandEndpoint() const;

View File

@ -13,6 +13,7 @@ set(remote_SOURCES
apilistener.cpp apilistener.hpp apilistener-ti.hpp apilistener-configsync.cpp apilistener-filesync.cpp
apilistener-authority.cpp
apiuser.cpp apiuser.hpp apiuser-ti.hpp
crproducer.hpp
configfileshandler.cpp configfileshandler.hpp
configobjectslock.cpp configobjectslock.hpp
configobjectutility.cpp configobjectutility.hpp

34
lib/remote/crproducer.hpp Normal file
View File

@ -0,0 +1,34 @@
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
#pragma once
#include "base/object.hpp"
namespace icinga
{
/**
* A component that produces check results and hence is responsible for them, e.g. CheckerComponent.
* I.e. on its shutdown it has to clean up and/or wait for its own ongoing checks if any.
*
* @ingroup icinga
*/
class CheckResultProducer : virtual public Object
{
public:
DECLARE_PTR_TYPEDEFS(CheckResultProducer);
/**
* Requests to delay the producer shutdown (if any) for a CheckResult to be processed.
*
* @return Whether request was accepted.
*/
virtual bool try_lock_shared() noexcept = 0;
/**
* Releases one semaphore slot acquired for CheckResult processing.
*/
virtual void unlock_shared() noexcept = 0;
};
}