for (;;) {
Service service = m_Services.top();
- if (service.GetNextCheck() > now)
+ if (service.GetNextCheck() > now || service.HasPendingCheck())
break;
+ m_Services.pop();
+ service.SetPendingCheck(true);
+
Application::Log(LogInformation, "checker", "Executing service check for '" + service.GetName() + "'");
CheckTask::Ptr task = CheckTask::CreateTask(service);
task->Execute();
m_PendingTasks.push_back(task);
- m_Services.pop();
service.SetNextCheck(now + service.GetCheckInterval());
m_Services.push(service);
}
- /* adjust next call time for the check timer */
- Service service = m_Services.top();
- m_CheckTimer->SetInterval(service.GetNextCheck() - now);
+ AdjustCheckTimer();
}
void CheckerComponent::ResultTimerHandler(void)
continue;
}
+ task->GetService().SetPendingCheck(false);
+
CheckResult result = task->GetResult();
Application::Log(LogInformation, "checker", "Got result! Plugin output: " + result.Output);
}
m_PendingTasks = unfinishedTasks;
+
+ AdjustCheckTimer();
+}
+
+void CheckerComponent::AdjustCheckTimer(void)
+{
+ if (m_Services.size() == 0)
+ return;
+
+ /* adjust next call time for the check timer */
+ Service service = m_Services.top();
+
+ if (service.HasPendingCheck()) {
+ m_CheckTimer->Stop();
+ } else {
+ m_CheckTimer->SetInterval(service.GetNextCheck() - time(NULL));
+ m_CheckTimer->Start();
+ }
}
void CheckerComponent::AssignServiceRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request)
namespace icinga
{
-struct ServiceNextCheckGreaterComparer
+struct ServiceCheckPriorityLessComparer
{
public:
bool operator()(const Service& a, const Service& b)
{
+ if (a.HasPendingCheck() && !b.HasPendingCheck())
+ return true;
+
return a.GetNextCheck() > b.GetNextCheck();
}
};
typedef shared_ptr<CheckerComponent> Ptr;
typedef weak_ptr<CheckerComponent> WeakPtr;
- typedef priority_queue<Service, vector<Service>, ServiceNextCheckGreaterComparer> ServiceQueue;
+ typedef priority_queue<Service, vector<Service>, ServiceCheckPriorityLessComparer> ServiceQueue;
virtual string GetName(void) const;
virtual void Start(void);
void CheckTimerHandler(void);
void ResultTimerHandler(void);
+ void AdjustCheckTimer(void);
+
void AssignServiceRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request);
void RevokeServiceRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request);
void ClearServicesRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request);
map<string, CheckTask::Factory> CheckTask::m_Types;
+CheckTask::CheckTask(const Service& service)
+ : m_Service(service)
+{ }
+
+Service CheckTask::GetService(void) const
+{
+ return m_Service;
+}
+
void CheckTask::RegisterType(string type, Factory factory)
{
m_Types[type] = factory;
typedef function<CheckTask::Ptr(const Service&)> Factory;
+ Service GetService(void) const;
+
virtual void Execute(void) = 0;
virtual bool IsFinished(void) const = 0;
virtual CheckResult GetResult(void) = 0;
static void RegisterType(string type, Factory factory);
static CheckTask::Ptr CreateTask(const Service& service);
+protected:
+ CheckTask(const Service& service);
+
private:
+ Service m_Service;
+
static map<string, Factory> m_Types;
};
using namespace icinga;
NagiosCheckTask::NagiosCheckTask(const Service& service)
+ : CheckTask(service)
{
string checkCommand = service.GetCheckCommand();
m_Command = MacroProcessor::ResolveMacros(checkCommand, service.GetMacros()) + " 2>&1";
GetConfigObject()->GetTag("checker", &value);
return value;
}
+
+void Service::SetPendingCheck(bool pending)
+{
+ GetConfigObject()->SetTag("pendingCheck", pending);
+}
+
+bool Service::HasPendingCheck(void) const
+{
+ bool value = false;
+ GetConfigObject()->GetTag("pendingCheck", &value);
+ return value;
+}
\ No newline at end of file
time_t GetNextCheck(void) const;
void SetChecker(string checker);
string GetChecker(void) const;
+ void SetPendingCheck(bool pending);
+ bool HasPendingCheck(void) const;
};
}