From 6adf2d19e437860fd3f71f5746ed5902e9527f3b Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 3 Apr 2023 15:39:50 +0200 Subject: [PATCH] Remove -and notify- expired downtimes immediately, not every 60s Don't look for expired downtimes in a timer fired every 60s, but fire one timer per downtime once at expire time. --- lib/icinga/downtime.cpp | 45 ++++++++++++++++++++++++++++++++++++++++- lib/icinga/downtime.hpp | 7 +++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/icinga/downtime.cpp b/lib/icinga/downtime.cpp index 99ffd03ec..f556eaa72 100644 --- a/lib/icinga/downtime.cpp +++ b/lib/icinga/downtime.cpp @@ -10,6 +10,7 @@ #include "base/timer.hpp" #include #include +#include using namespace icinga; @@ -159,6 +160,21 @@ void Downtime::Stop(bool runtimeRemoved) ObjectImpl::Stop(runtimeRemoved); } +void Downtime::Pause() +{ + if (m_CleanupTimer) { + m_CleanupTimer->Stop(); + } + + ObjectImpl::Pause(); +} + +void Downtime::Resume() +{ + ObjectImpl::Resume(); + SetupCleanupTimer(); +} + Checkable::Ptr Downtime::GetCheckable() const { return static_pointer_cast(m_Checkable); @@ -427,6 +443,28 @@ bool Downtime::CanBeTriggered() return true; } +void Downtime::SetupCleanupTimer() +{ + if (!m_CleanupTimer) { + m_CleanupTimer = Timer::Create(); + + auto name (GetName()); + + m_CleanupTimer->OnTimerExpired.connect([name=std::move(name)](const Timer * const&) { + auto downtime (Downtime::GetByName(name)); + + if (downtime && downtime->IsExpired()) { + RemoveDowntime(name, false, false, true); + } + }); + } + + auto triggerTime (GetTriggerTime()); + + m_CleanupTimer->Reschedule((GetFixed() || triggerTime <= 0 ? GetEndTime() : triggerTime + GetDuration()) + 0.1); + m_CleanupTimer->Start(); +} + void Downtime::TriggerDowntime(double triggerTime) { if (!CanBeTriggered()) @@ -441,6 +479,11 @@ void Downtime::TriggerDowntime(double triggerTime) SetTriggerTime(triggerTime); } + { + ObjectLock olock (this); + SetupCleanupTimer(); + } + Array::Ptr triggers = GetTriggers(); { @@ -501,7 +544,7 @@ void Downtime::DowntimesExpireTimerHandler() { for (const Downtime::Ptr& downtime : ConfigType::GetObjectsByType()) { /* Only remove downtimes which are activated after daemon start. */ - if (downtime->IsActive() && (downtime->IsExpired() || !downtime->HasValidConfigOwner())) + if (downtime->IsActive() && !downtime->HasValidConfigOwner()) RemoveDowntime(downtime->GetName(), false, false, true); } } diff --git a/lib/icinga/downtime.hpp b/lib/icinga/downtime.hpp index 5f0c4937b..8629da1d9 100644 --- a/lib/icinga/downtime.hpp +++ b/lib/icinga/downtime.hpp @@ -72,6 +72,9 @@ protected: void Start(bool runtimeCreated) override; void Stop(bool runtimeRemoved) override; + void Pause() override; + void Resume() override; + void ValidateStartTime(const Lazy& lvalue, const ValidationUtils& utils) override; void ValidateEndTime(const Lazy& lvalue, const ValidationUtils& utils) override; @@ -81,8 +84,12 @@ private: std::set m_Children; mutable std::mutex m_ChildrenMutex; + Timer::Ptr m_CleanupTimer; + bool CanBeTriggered(); + void SetupCleanupTimer(); + static void DowntimesStartTimerHandler(); static void DowntimesExpireTimerHandler(); };