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

View File

@ -74,6 +74,7 @@ private:
Dictionary::Ptr FetchRow(MYSQL_RES *result);
bool FieldToEscapedString(const String& key, const Value& value, Value *result);
void InternalActivateObject(const DbObject::Ptr& dbobj);
void TxTimerHandler(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 (double, const std::set<DynamicObject::WeakPtr>&)> DynamicObject::OnTransactionClosing;
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)
: m_ConfigTx(0), m_LocalTx(0), m_Registered(false)
@ -627,6 +628,8 @@ void DynamicObject::NewTx(void)
attrs.swap(object->m_ModifiedAttributes);
}
OnAttributesChanged(object, attrs);
BOOST_FOREACH(const String& attr, attrs) {
object->OnAttributeChanged(attr);
}

View File

@ -69,6 +69,7 @@ public:
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 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);

View File

@ -23,6 +23,7 @@
#include "base/dynamictype.h"
#include "base/objectlock.h"
#include "base/utility.h"
#include "base/logger_fwd.h"
#include <boost/foreach.hpp>
using namespace icinga;
@ -32,15 +33,14 @@ boost::signals2::signal<void (const DbObject::Ptr&)> DbObject::OnUnregistered;
boost::signals2::signal<void (const DbQuery&)> DbObject::OnQuery;
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)
{
DynamicObject::OnRegistered.connect(boost::bind(&DbObject::ObjectRegisteredHandler, _1));
DynamicObject::OnUnregistered.connect(boost::bind(&DbObject::ObjectUnregisteredHandler, _1));
// DynamicObject::OnTransactionClosing.connect(boost::bind(&DbObject::TransactionClosingHandler, _1, _2));
// DynamicObject::OnFlushObject.connect(boost::bind(&DbObject::FlushObjectHandler, _1, _2));
DynamicObject::OnAttributesChanged.connect(boost::bind(&DbObject::AttributesChangedHandler, _1, _2));
}
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("config_type", 1);
OnQuery(query2);
m_LastConfigUpdate = Utility::GetTime();
}
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("status_update_time", Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", Utility::GetTime()));
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)
@ -145,7 +178,7 @@ DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
name1 = object->GetName();
}
dbobj = dbtype->GetOrCreateObjectByName(object->GetName(), String());
dbobj = dbtype->GetOrCreateObjectByName(name1, name2);
{
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)
//{
// BOOST_FOREACH(const DynamicObject::WeakPtr& wobject, modifiedObjects) {
// DynamicObject::Ptr object = wobject.lock();
//
// if (!object)
// continue;
//
// FlushObjectHandler(tx, object);
// }
//}
//
//void DbObject::FlushObjectHandler(double tx, const DynamicObject::Ptr& object)
//{
// DbObject::Ptr dbobj = GetOrCreateByObject(object);
//
// if (!dbobj)
// return;
//
// dbobj->SendUpdate();
//}
void DbObject::AttributesChangedHandler(const DynamicObject::Ptr& object, const std::set<String, string_iless>& attributes)
{
DbObject::Ptr dbobj = GetOrCreateByObject(object);
if (!dbobj)
return;
bool configUpdate = false, statusUpdate = false;
BOOST_FOREACH(const String& attribute, attributes) {
if (!configUpdate && dbobj->IsConfigAttribute(attribute))
configUpdate = true;
if (!statusUpdate && dbobj->IsStatusAttribute(attribute))
statusUpdate = true;
}
if (configUpdate)
dbobj->SendConfigUpdate();
if (statusUpdate)
dbobj->SendStatusUpdate();
}

View File

@ -65,14 +65,22 @@ public:
void SendConfigUpdate(void);
void SendStatusUpdate(void);
double GetLastConfigUpdate(void) const;
double GetLastStatusUpdate(void) const;
protected:
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:
String m_Name1;
String m_Name2;
boost::shared_ptr<DbType> m_Type;
DynamicObject::Ptr m_Object;
double m_LastConfigUpdate;
double m_LastStatusUpdate;
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 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 FlushObjectHandler(double tx, const DynamicObject::Ptr& object);

View File

@ -145,4 +145,9 @@ Dictionary::Ptr ServiceDbObject::GetStatusFields(void) const
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 GetStatusFields(void) const;
virtual bool IsStatusAttribute(const String& attribute) const;
};
}