Implement status updates for services.

This commit is contained in:
Gunnar Beutner 2013-07-24 10:55:04 +02:00
parent 3a552403eb
commit 28726e5025
8 changed files with 88 additions and 27 deletions

View File

@ -244,7 +244,11 @@ Dictionary::Ptr MysqlDbConnection::FetchRow(MYSQL_RES *result)
void MysqlDbConnection::ActivateObject(const DbObject::Ptr& dbobj) void MysqlDbConnection::ActivateObject(const DbObject::Ptr& dbobj)
{ {
boost::mutex::scoped_lock lock(m_ConnectionMutex); boost::mutex::scoped_lock lock(m_ConnectionMutex);
InternalActivateObject(dbobj);
}
void MysqlDbConnection::InternalActivateObject(const DbObject::Ptr& dbobj)
{
if (!m_Connected) if (!m_Connected)
return; return;
@ -282,6 +286,7 @@ void MysqlDbConnection::DeactivateObject(const DbObject::Ptr& dbobj)
SetReference(dbobj, DbReference()); SetReference(dbobj, DbReference());
} }
/* caller must hold m_ConnectionMutex */
bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& value, Value *result) bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& value, Value *result)
{ {
if (key == "instance_id") { if (key == "instance_id") {
@ -300,7 +305,7 @@ bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& val
DbReference dbrefcol = GetReference(dbobjcol); DbReference dbrefcol = GetReference(dbobjcol);
if (!dbrefcol.IsValid()) { if (!dbrefcol.IsValid()) {
ActivateObject(dbobjcol); InternalActivateObject(dbobjcol);
dbrefcol = GetReference(dbobjcol); dbrefcol = GetReference(dbobjcol);
@ -310,7 +315,7 @@ bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& val
*result = static_cast<long>(dbrefcol); *result = static_cast<long>(dbrefcol);
} else if (DbValue::IsTimestamp(value)) { } else if (DbValue::IsTimestamp(value)) {
double ts = DbValue::ExtractValue(value); long ts = DbValue::ExtractValue(value);
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "FROM_UNIXTIME(" << ts << ")"; msgbuf << "FROM_UNIXTIME(" << ts << ")";
*result = Value(msgbuf.str()); *result = Value(msgbuf.str());

View File

@ -74,6 +74,7 @@ private:
Dictionary::Ptr FetchRow(MYSQL_RES *result); Dictionary::Ptr FetchRow(MYSQL_RES *result);
bool FieldToEscapedString(const String& key, const Value& value, Value *result); bool FieldToEscapedString(const String& key, const Value& value, Value *result);
void InternalActivateObject(const DbObject::Ptr& dbobj);
void TxTimerHandler(void); void TxTimerHandler(void);
void ReconnectTimerHandler(void); void ReconnectTimerHandler(void);

View File

@ -47,6 +47,7 @@ boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnRegis
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered; boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered;
boost::signals2::signal<void (double, const std::set<DynamicObject::WeakPtr>&)> DynamicObject::OnTransactionClosing; boost::signals2::signal<void (double, const std::set<DynamicObject::WeakPtr>&)> DynamicObject::OnTransactionClosing;
boost::signals2::signal<void (double, const DynamicObject::Ptr&)> DynamicObject::OnFlushObject; boost::signals2::signal<void (double, const DynamicObject::Ptr&)> DynamicObject::OnFlushObject;
boost::signals2::signal<void (const DynamicObject::Ptr&, const std::set<String, string_iless>&)> DynamicObject::OnAttributesChanged;
DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject) DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
: m_ConfigTx(0), m_LocalTx(0), m_Registered(false) : m_ConfigTx(0), m_LocalTx(0), m_Registered(false)
@ -627,6 +628,8 @@ void DynamicObject::NewTx(void)
attrs.swap(object->m_ModifiedAttributes); attrs.swap(object->m_ModifiedAttributes);
} }
OnAttributesChanged(object, attrs);
BOOST_FOREACH(const String& attr, attrs) { BOOST_FOREACH(const String& attr, attrs) {
object->OnAttributeChanged(attr); object->OnAttributeChanged(attr);
} }

View File

@ -69,6 +69,7 @@ public:
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnUnregistered; static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnUnregistered;
static boost::signals2::signal<void (double, const std::set<DynamicObject::WeakPtr>&)> OnTransactionClosing; static boost::signals2::signal<void (double, const std::set<DynamicObject::WeakPtr>&)> OnTransactionClosing;
static boost::signals2::signal<void (double, const DynamicObject::Ptr&)> OnFlushObject; static boost::signals2::signal<void (double, const DynamicObject::Ptr&)> OnFlushObject;
static boost::signals2::signal<void (const DynamicObject::Ptr&, const std::set<String, string_iless>&)> OnAttributesChanged;
Value InvokeMethod(const String& method, const std::vector<Value>& arguments); Value InvokeMethod(const String& method, const std::vector<Value>& arguments);

View File

@ -23,6 +23,7 @@
#include "base/dynamictype.h" #include "base/dynamictype.h"
#include "base/objectlock.h" #include "base/objectlock.h"
#include "base/utility.h" #include "base/utility.h"
#include "base/logger_fwd.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
using namespace icinga; using namespace icinga;
@ -32,15 +33,14 @@ boost::signals2::signal<void (const DbObject::Ptr&)> DbObject::OnUnregistered;
boost::signals2::signal<void (const DbQuery&)> DbObject::OnQuery; boost::signals2::signal<void (const DbQuery&)> DbObject::OnQuery;
DbObject::DbObject(const shared_ptr<DbType>& type, const String& name1, const String& name2) DbObject::DbObject(const shared_ptr<DbType>& type, const String& name1, const String& name2)
: m_Name1(name1), m_Name2(name2), m_Type(type) : m_Name1(name1), m_Name2(name2), m_Type(type), m_LastConfigUpdate(0), m_LastStatusUpdate(0)
{ } { }
void DbObject::StaticInitialize(void) void DbObject::StaticInitialize(void)
{ {
DynamicObject::OnRegistered.connect(boost::bind(&DbObject::ObjectRegisteredHandler, _1)); DynamicObject::OnRegistered.connect(boost::bind(&DbObject::ObjectRegisteredHandler, _1));
DynamicObject::OnUnregistered.connect(boost::bind(&DbObject::ObjectUnregisteredHandler, _1)); DynamicObject::OnUnregistered.connect(boost::bind(&DbObject::ObjectUnregisteredHandler, _1));
// DynamicObject::OnTransactionClosing.connect(boost::bind(&DbObject::TransactionClosingHandler, _1, _2)); DynamicObject::OnAttributesChanged.connect(boost::bind(&DbObject::AttributesChangedHandler, _1, _2));
// DynamicObject::OnFlushObject.connect(boost::bind(&DbObject::FlushObjectHandler, _1, _2));
} }
void DbObject::SetObject(const DynamicObject::Ptr& object) void DbObject::SetObject(const DynamicObject::Ptr& object)
@ -90,6 +90,8 @@ void DbObject::SendConfigUpdate(void)
query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */ query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.Fields->Set("config_type", 1); query2.Fields->Set("config_type", 1);
OnQuery(query2); OnQuery(query2);
m_LastConfigUpdate = Utility::GetTime();
} }
void DbObject::SendStatusUpdate(void) void DbObject::SendStatusUpdate(void)
@ -114,6 +116,37 @@ void DbObject::SendStatusUpdate(void)
query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */ query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.Fields->Set("status_update_time", Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", Utility::GetTime())); query2.Fields->Set("status_update_time", Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", Utility::GetTime()));
OnQuery(query2); OnQuery(query2);
m_LastStatusUpdate = Utility::GetTime();
}
double DbObject::GetLastConfigUpdate(void) const
{
return m_LastConfigUpdate;
}
double DbObject::GetLastStatusUpdate(void) const
{
return m_LastStatusUpdate;
}
bool DbObject::IsConfigAttribute(const String& attribute) const
{
DynamicObject::Ptr object = GetObject();
ObjectLock olock(object);
DynamicObject::AttributeConstIterator it;
it = object->GetAttributes().find(attribute);
if (it == object->GetAttributes().end())
return false;
return (it->second.GetType() == Attribute_Config);
}
bool DbObject::IsStatusAttribute(const String&) const
{
return false;
} }
DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object) DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
@ -145,7 +178,7 @@ DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
name1 = object->GetName(); name1 = object->GetName();
} }
dbobj = dbtype->GetOrCreateObjectByName(object->GetName(), String()); dbobj = dbtype->GetOrCreateObjectByName(name1, name2);
{ {
ObjectLock olock(object); ObjectLock olock(object);
@ -185,24 +218,26 @@ void DbObject::ObjectUnregisteredHandler(const DynamicObject::Ptr& object)
} }
} }
//void DbObject::TransactionClosingHandler(double tx, const std::set<DynamicObject::WeakPtr>& modifiedObjects) void DbObject::AttributesChangedHandler(const DynamicObject::Ptr& object, const std::set<String, string_iless>& attributes)
//{ {
// BOOST_FOREACH(const DynamicObject::WeakPtr& wobject, modifiedObjects) { DbObject::Ptr dbobj = GetOrCreateByObject(object);
// DynamicObject::Ptr object = wobject.lock();
// if (!dbobj)
// if (!object) return;
// continue;
// bool configUpdate = false, statusUpdate = false;
// FlushObjectHandler(tx, object);
// } BOOST_FOREACH(const String& attribute, attributes) {
//} if (!configUpdate && dbobj->IsConfigAttribute(attribute))
// configUpdate = true;
//void DbObject::FlushObjectHandler(double tx, const DynamicObject::Ptr& object)
//{ if (!statusUpdate && dbobj->IsStatusAttribute(attribute))
// DbObject::Ptr dbobj = GetOrCreateByObject(object); statusUpdate = true;
// }
// if (!dbobj)
// return; if (configUpdate)
// dbobj->SendConfigUpdate();
// dbobj->SendUpdate();
//} if (statusUpdate)
dbobj->SendStatusUpdate();
}

View File

@ -65,14 +65,22 @@ public:
void SendConfigUpdate(void); void SendConfigUpdate(void);
void SendStatusUpdate(void); void SendStatusUpdate(void);
double GetLastConfigUpdate(void) const;
double GetLastStatusUpdate(void) const;
protected: protected:
DbObject(const boost::shared_ptr<DbType>& type, const String& name1, const String& name2); DbObject(const boost::shared_ptr<DbType>& type, const String& name1, const String& name2);
virtual bool IsConfigAttribute(const String& attribute) const;
virtual bool IsStatusAttribute(const String& attribute) const;
private: private:
String m_Name1; String m_Name1;
String m_Name2; String m_Name2;
boost::shared_ptr<DbType> m_Type; boost::shared_ptr<DbType> m_Type;
DynamicObject::Ptr m_Object; DynamicObject::Ptr m_Object;
double m_LastConfigUpdate;
double m_LastStatusUpdate;
friend boost::shared_ptr<DbObject> boost::make_shared<>(const icinga::String&, const icinga::String&); friend boost::shared_ptr<DbObject> boost::make_shared<>(const icinga::String&, const icinga::String&);
@ -80,6 +88,7 @@ private:
static void ObjectRegisteredHandler(const DynamicObject::Ptr& object); static void ObjectRegisteredHandler(const DynamicObject::Ptr& object);
static void ObjectUnregisteredHandler(const DynamicObject::Ptr& object); static void ObjectUnregisteredHandler(const DynamicObject::Ptr& object);
static void AttributesChangedHandler(const DynamicObject::Ptr& object, const std::set<String, string_iless>& attributes);
//static void TransactionClosingHandler(double tx, const std::set<DynamicObject::WeakPtr>& modifiedObjects); //static void TransactionClosingHandler(double tx, const std::set<DynamicObject::WeakPtr>& modifiedObjects);
//static void FlushObjectHandler(double tx, const DynamicObject::Ptr& object); //static void FlushObjectHandler(double tx, const DynamicObject::Ptr& object);

View File

@ -145,4 +145,9 @@ Dictionary::Ptr ServiceDbObject::GetStatusFields(void) const
return fields; return fields;
}
bool ServiceDbObject::IsStatusAttribute(const String& attribute) const
{
return (attribute == "last_result");
} }

View File

@ -40,6 +40,8 @@ public:
virtual Dictionary::Ptr GetConfigFields(void) const; virtual Dictionary::Ptr GetConfigFields(void) const;
virtual Dictionary::Ptr GetStatusFields(void) const; virtual Dictionary::Ptr GetStatusFields(void) const;
virtual bool IsStatusAttribute(const String& attribute) const;
}; };
} }