Move service check code into the Service class.

Fixes #3546
This commit is contained in:
Gunnar Beutner 2013-01-22 11:07:09 +01:00
parent c97b480b1e
commit 8c2ab8f552
4 changed files with 94 additions and 65 deletions

View File

@ -64,9 +64,7 @@ void CheckerComponent::CheckTimerHandler(void)
CheckTimeView::iterator it = idx.begin(); CheckTimeView::iterator it = idx.begin();
Service::Ptr service = *it; Service::Ptr service = *it;
double next_check = service->GetNextCheck(); if (service->GetNextCheck() > now)
if (next_check > now)
break; break;
idx.erase(it); idx.erase(it);
@ -87,18 +85,7 @@ void CheckerComponent::CheckTimerHandler(void)
m_PendingServices.insert(service); m_PendingServices.insert(service);
/* keep track of scheduling info in case the check type doesn't provide its own information */ service->BeginExecuteCheck(boost::bind(&CheckerComponent::CheckCompletedHandler, this, service));
Dictionary::Ptr scheduleInfo = boost::make_shared<Dictionary>();
scheduleInfo->Set("schedule_start", next_check);
scheduleInfo->Set("execution_start", Utility::GetTime());
vector<Value> arguments;
arguments.push_back(service);
ScriptTask::Ptr task;
task = service->InvokeMethod("check", arguments, boost::bind(&CheckerComponent::CheckCompletedHandler, this, service, scheduleInfo, _1));
assert(task); /* TODO: gracefully handle missing methods */
service->Set("current_task", task);
tasks++; tasks++;
} }
@ -118,56 +105,8 @@ void CheckerComponent::CheckTimerHandler(void)
} }
} }
void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service, const Dictionary::Ptr& scheduleInfo, const ScriptTask::Ptr& task) void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service)
{ {
service->Set("current_task", Empty);
scheduleInfo->Set("execution_end", Utility::GetTime());
scheduleInfo->Set("schedule_end", Utility::GetTime());
try {
Value vresult = task->GetResult();
if (vresult.IsObjectType<Dictionary>()) {
Dictionary::Ptr result = vresult;
if (!result->Contains("schedule_start"))
result->Set("schedule_start", scheduleInfo->Get("schedule_start"));
if (!result->Contains("schedule_end"))
result->Set("schedule_end", scheduleInfo->Get("schedule_end"));
if (!result->Contains("execution_start"))
result->Set("execution_start", scheduleInfo->Get("execution_start"));
if (!result->Contains("execution_end"))
result->Set("execution_end", scheduleInfo->Get("execution_end"));
service->ApplyCheckResult(result);
RequestMessage rm;
rm.SetMethod("checker::ServiceStateChange");
/* TODO: add _old_ state to message */
ServiceStateChangeMessage params;
params.SetService(service->GetName());
rm.SetParams(params);
EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, rm);
}
} catch (const exception& ex) {
stringstream msgbuf;
msgbuf << "Exception occured during check for service '"
<< service->GetName() << "': " << ex.what();
Logger::Write(LogWarning, "checker", msgbuf.str());
}
/* figure out when the next check is for this service; the call to
* ApplyCheckResult() should've already done this but lets do it again
* just in case there was no check result. */
service->UpdateNextCheck();
/* remove the service from the list of pending services; if it's not in the /* remove the service from the list of pending services; if it's not in the
* list this was a manual (i.e. forced) check and we must not re-add the * list this was a manual (i.e. forced) check and we must not re-add the
* service to the services list because it's already there. */ * service to the services list because it's already there. */

View File

@ -69,7 +69,7 @@ private:
void CheckTimerHandler(void); void CheckTimerHandler(void);
void ResultTimerHandler(void); void ResultTimerHandler(void);
void CheckCompletedHandler(const Service::Ptr& service, const Dictionary::Ptr& scheduleInfo, const ScriptTask::Ptr& task); void CheckCompletedHandler(const Service::Ptr& service);
void AdjustCheckTimer(void); void AdjustCheckTimer(void);

View File

@ -480,3 +480,86 @@ void Service::OnAttributeChanged(const String& name, const Value& oldValue)
if (name == "checker") if (name == "checker")
OnCheckerChanged(GetSelf(), oldValue); OnCheckerChanged(GetSelf(), oldValue);
} }
void Service::BeginExecuteCheck(const function<void (void)>& callback)
{
/* don't run another check if there is one pending */
if (Get("current_task")) {
/* we need to call the callback anyway */
callback();
return;
}
/* keep track of scheduling info in case the check type doesn't provide its own information */
Dictionary::Ptr scheduleInfo = boost::make_shared<Dictionary>();
scheduleInfo->Set("schedule_start", GetNextCheck());
scheduleInfo->Set("execution_start", Utility::GetTime());
vector<Value> arguments;
arguments.push_back(static_cast<Service::Ptr>(GetSelf()));
ScriptTask::Ptr task;
task = InvokeMethod("check", arguments, boost::bind(&Service::CheckCompletedHandler, this, scheduleInfo, _1, callback));
assert(task); /* TODO: gracefully handle missing methods */
Set("current_task", task);
}
void Service::CheckCompletedHandler(const Dictionary::Ptr& scheduleInfo,
const ScriptTask::Ptr& task, const function<void (void)>& callback)
{
Set("current_task", Empty);
scheduleInfo->Set("execution_end", Utility::GetTime());
scheduleInfo->Set("schedule_end", Utility::GetTime());
try {
Value vresult = task->GetResult();
if (vresult.IsObjectType<Dictionary>()) {
Dictionary::Ptr result = vresult;
if (!result->Contains("schedule_start"))
result->Set("schedule_start", scheduleInfo->Get("schedule_start"));
if (!result->Contains("schedule_end"))
result->Set("schedule_end", scheduleInfo->Get("schedule_end"));
if (!result->Contains("execution_start"))
result->Set("execution_start", scheduleInfo->Get("execution_start"));
if (!result->Contains("execution_end"))
result->Set("execution_end", scheduleInfo->Get("execution_end"));
ProcessCheckResult(result);
}
} catch (const exception& ex) {
stringstream msgbuf;
msgbuf << "Exception occured during check for service '"
<< GetName() << "': " << ex.what();
Logger::Write(LogWarning, "checker", msgbuf.str());
}
/* figure out when the next check is for this service; the call to
* ApplyCheckResult() should've already done this but lets do it again
* just in case there was no check result. */
UpdateNextCheck();
callback();
}
void Service::ProcessCheckResult(const Dictionary::Ptr& cr)
{
ApplyCheckResult(cr);
RequestMessage rm;
rm.SetMethod("checker::ServiceStateChange");
/* TODO: add _old_ state to message */
ServiceStateChangeMessage params;
params.SetService(GetName());
rm.SetParams(params);
EndpointManager::GetInstance()->SendMulticastMessage(rm);
}

View File

@ -118,6 +118,9 @@ public:
void ApplyCheckResult(const Dictionary::Ptr& cr); void ApplyCheckResult(const Dictionary::Ptr& cr);
void BeginExecuteCheck(const function<void (void)>& callback);
void ProcessCheckResult(const Dictionary::Ptr& cr);
static ServiceState StateFromString(const String& state); static ServiceState StateFromString(const String& state);
static String StateToString(ServiceState state); static String StateToString(ServiceState state);
@ -131,6 +134,10 @@ public:
protected: protected:
virtual void OnAttributeChanged(const String& name, const Value& oldValue); virtual void OnAttributeChanged(const String& name, const Value& oldValue);
private:
void CheckCompletedHandler(const Dictionary::Ptr& scheduleInfo,
const ScriptTask::Ptr& task, const function<void (void)>& callback);
}; };
} }