Downtime::OnDowntimeAdded.connect(&ApiEvents::DowntimeAddedHandler);
Downtime::OnDowntimeRemoved.connect(&ApiEvents::DowntimeRemovedHandler);
+ Downtime::OnDowntimeStarted.connect(&ApiEvents::DowntimeStartedHandler);
Downtime::OnDowntimeTriggered.connect(&ApiEvents::DowntimeTriggeredHandler);
}
}
}
+void ApiEvents::DowntimeStartedHandler(const Downtime::Ptr& downtime)
+{
+ std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeStarted");
+
+ if (queues.empty())
+ return;
+
+ Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeStarted'.");
+
+ Dictionary::Ptr result = new Dictionary();
+ result->Set("type", "DowntimeStarted");
+ result->Set("timestamp", Utility::GetTime());
+
+ result->Set("downtime", Serialize(downtime, FAConfig | FAState));
+
+ for (const EventQueue::Ptr& queue : queues) {
+ queue->ProcessEvent(result);
+ }
+}
+
void ApiEvents::DowntimeTriggeredHandler(const Downtime::Ptr& downtime)
{
std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeTriggered");
static boost::mutex l_DowntimeMutex;
static std::map<int, String> l_LegacyDowntimesCache;
static Timer::Ptr l_DowntimesExpireTimer;
+static Timer::Ptr l_DowntimesStartTimer;
boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeAdded;
boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeRemoved;
+boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeStarted;
boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeTriggered;
INITIALIZE_ONCE(&Downtime::StaticInitialize);
void Downtime::StaticInitialize(void)
{
+ l_DowntimesStartTimer = new Timer();
+ l_DowntimesStartTimer->SetInterval(5);
+ l_DowntimesStartTimer->OnTimerExpired.connect(boost::bind(&Downtime::DowntimesStartTimerHandler));
+ l_DowntimesStartTimer->Start();
+
l_DowntimesExpireTimer = new Timer();
l_DowntimesExpireTimer->SetInterval(60);
l_DowntimesExpireTimer->OnTimerExpired.connect(boost::bind(&Downtime::DowntimesExpireTimerHandler));
}
}
-void Downtime::TriggerDowntime(void)
+bool Downtime::CanBeTriggered(void)
{
- if (IsInEffect() && IsTriggered()) {
- Log(LogDebug, "Downtime")
- << "Not triggering downtime '" << GetName() << "': already triggered.";
- return;
- }
+ if (IsInEffect() && IsTriggered())
+ return false;
- if (IsExpired()) {
- Log(LogDebug, "Downtime")
- << "Not triggering downtime '" << GetName() << "': expired.";
- return;
- }
+ if (IsExpired())
+ return false;
double now = Utility::GetTime();
- if (now < GetStartTime() || now > GetEndTime()) {
- Log(LogDebug, "Downtime")
- << "Not triggering downtime '" << GetName() << "': current time is outside downtime window.";
+ if (now < GetStartTime() || now > GetEndTime())
+ return false;
+
+ return true;
+}
+
+void Downtime::TriggerDowntime(void)
+{
+ if (!CanBeTriggered())
return;
- }
Log(LogNotice, "Downtime")
<< "Triggering downtime '" << GetName() << "'.";
return it->second;
}
+void Downtime::DowntimesStartTimerHandler(void)
+{
+ /* Start fixed downtimes. Flexible downtimes will be triggered on-demand. */
+ for (const Downtime::Ptr& downtime : ConfigType::GetObjectsByType<Downtime>()) {
+ if (downtime->IsActive() &&
+ downtime->CanBeTriggered() &&
+ downtime->GetFixed()) {
+ /* Send notifications. */
+ OnDowntimeStarted(downtime);
+
+ /* Trigger fixed downtime immediately. */
+ downtime->TriggerDowntime();
+ }
+ }
+}
+
void Downtime::DowntimesExpireTimerHandler(void)
{
std::vector<Downtime::Ptr> downtimes;
static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeAdded;
static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeRemoved;
+ static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeStarted;
static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeTriggered;
intrusive_ptr<Checkable> GetCheckable(void) const;
private:
ObjectImpl<Checkable>::Ptr m_Checkable;
+ bool CanBeTriggered(void);
+
+ static void DowntimesStartTimerHandler(void);
static void DowntimesExpireTimerHandler(void);
};