mirror of https://github.com/Icinga/icinga2.git
Bugfix: Local events for changed attributes aren't processed at transaction commit time.
Fixes #3605
This commit is contained in:
parent
f725c6ee7a
commit
6c23481a55
|
@ -155,7 +155,7 @@ void ReplicationComponent::LocalObjectUnregisteredHandler(const DynamicObject::P
|
||||||
MakeObjectMessage(object, "config::ObjectRemoved", 0, false));
|
MakeObjectMessage(object, "config::ObjectRemoved", 0, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplicationComponent::TransactionClosingHandler(const set<DynamicObject::Ptr>& modifiedObjects)
|
void ReplicationComponent::TransactionClosingHandler(const set<DynamicObject *>& modifiedObjects)
|
||||||
{
|
{
|
||||||
if (modifiedObjects.empty())
|
if (modifiedObjects.empty())
|
||||||
return;
|
return;
|
||||||
|
@ -164,7 +164,9 @@ void ReplicationComponent::TransactionClosingHandler(const set<DynamicObject::Pt
|
||||||
msgbuf << "Sending " << modifiedObjects.size() << " replication updates.";
|
msgbuf << "Sending " << modifiedObjects.size() << " replication updates.";
|
||||||
Logger::Write(LogDebug, "replication", msgbuf.str());
|
Logger::Write(LogDebug, "replication", msgbuf.str());
|
||||||
|
|
||||||
BOOST_FOREACH(const DynamicObject::Ptr& object, modifiedObjects) {
|
BOOST_FOREACH(DynamicObject *robject, modifiedObjects) {
|
||||||
|
DynamicObject::Ptr object = robject->GetSelf();
|
||||||
|
|
||||||
if (!ShouldReplicateObject(object))
|
if (!ShouldReplicateObject(object))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ private:
|
||||||
|
|
||||||
void LocalObjectRegisteredHandler(const DynamicObject::Ptr& object);
|
void LocalObjectRegisteredHandler(const DynamicObject::Ptr& object);
|
||||||
void LocalObjectUnregisteredHandler(const DynamicObject::Ptr& object);
|
void LocalObjectUnregisteredHandler(const DynamicObject::Ptr& object);
|
||||||
void TransactionClosingHandler(const set<DynamicObject::Ptr>& modifiedObjects);
|
void TransactionClosingHandler(const set<DynamicObject *>& modifiedObjects);
|
||||||
|
|
||||||
void RemoteObjectUpdateHandler(const RequestMessage& request);
|
void RemoteObjectUpdateHandler(const RequestMessage& request);
|
||||||
void RemoteObjectRemovedHandler(const RequestMessage& request);
|
void RemoteObjectRemovedHandler(const RequestMessage& request);
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
double DynamicObject::m_CurrentTx = 0;
|
double DynamicObject::m_CurrentTx = 0;
|
||||||
set<DynamicObject::Ptr> DynamicObject::m_ModifiedObjects;
|
set<DynamicObject *> DynamicObject::m_ModifiedObjects;
|
||||||
|
|
||||||
boost::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnRegistered;
|
boost::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnRegistered;
|
||||||
boost::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered;
|
boost::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered;
|
||||||
boost::signal<void (const set<DynamicObject::Ptr>&)> DynamicObject::OnTransactionClosing;
|
boost::signal<void (const set<DynamicObject *>&)> DynamicObject::OnTransactionClosing;
|
||||||
|
|
||||||
DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
||||||
: m_ConfigTx(0)
|
: m_ConfigTx(0)
|
||||||
|
@ -44,7 +44,22 @@ DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
||||||
/* apply config state from the config item/remote update;
|
/* apply config state from the config item/remote update;
|
||||||
* The DynamicObject::Create function takes care of restoring
|
* The DynamicObject::Create function takes care of restoring
|
||||||
* non-config state after the object has been fully constructed */
|
* non-config state after the object has been fully constructed */
|
||||||
InternalApplyUpdate(serializedObject, Attribute_Config, true);
|
ApplyUpdate(serializedObject, Attribute_Config);
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicObject::~DynamicObject(void)
|
||||||
|
{
|
||||||
|
m_ModifiedObjects.erase(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicObject::SendLocalUpdateEvents(void)
|
||||||
|
{
|
||||||
|
map<String, Value, string_iless>::iterator it;
|
||||||
|
for (it = m_ModifiedAttributes.begin(); it != m_ModifiedAttributes.end(); it++) {
|
||||||
|
OnAttributeChanged(it->first, it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ModifiedAttributes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary::Ptr DynamicObject::BuildUpdate(double sinceTx, int attributeTypes) const
|
Dictionary::Ptr DynamicObject::BuildUpdate(double sinceTx, int attributeTypes) const
|
||||||
|
@ -87,12 +102,6 @@ Dictionary::Ptr DynamicObject::BuildUpdate(double sinceTx, int attributeTypes) c
|
||||||
|
|
||||||
void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
||||||
int allowedTypes)
|
int allowedTypes)
|
||||||
{
|
|
||||||
InternalApplyUpdate(serializedUpdate, allowedTypes, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynamicObject::InternalApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
|
||||||
int allowedTypes, bool suppressEvents)
|
|
||||||
{
|
{
|
||||||
double configTx = 0;
|
double configTx = 0;
|
||||||
if ((allowedTypes & Attribute_Config) != 0 &&
|
if ((allowedTypes & Attribute_Config) != 0 &&
|
||||||
|
@ -126,7 +135,7 @@ void DynamicObject::InternalApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
||||||
if (!HasAttribute(it->first))
|
if (!HasAttribute(it->first))
|
||||||
RegisterAttribute(it->first, static_cast<DynamicAttributeType>(type));
|
RegisterAttribute(it->first, static_cast<DynamicAttributeType>(type));
|
||||||
|
|
||||||
InternalSetAttribute(it->first, data, tx, suppressEvents, true);
|
InternalSetAttribute(it->first, data, tx, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +169,7 @@ Value DynamicObject::Get(const String& name) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicObject::InternalSetAttribute(const String& name, const Value& data,
|
void DynamicObject::InternalSetAttribute(const String& name, const Value& data,
|
||||||
double tx, bool suppressEvent, bool allowEditConfig)
|
double tx, bool allowEditConfig)
|
||||||
{
|
{
|
||||||
DynamicAttribute attr;
|
DynamicAttribute attr;
|
||||||
attr.Type = Attribute_Transient;
|
attr.Type = Attribute_Transient;
|
||||||
|
@ -184,10 +193,12 @@ void DynamicObject::InternalSetAttribute(const String& name, const Value& data,
|
||||||
if (tt.first->second.Type & Attribute_Config)
|
if (tt.first->second.Type & Attribute_Config)
|
||||||
m_ConfigTx = tx;
|
m_ConfigTx = tx;
|
||||||
|
|
||||||
if (!suppressEvent) {
|
m_ModifiedObjects.insert(this);
|
||||||
m_ModifiedObjects.insert(GetSelf());
|
|
||||||
OnAttributeChanged(name, oldValue);
|
/* Use insert() rather than [] so we don't overwrite
|
||||||
}
|
* an existing oldValue if the attribute was previously
|
||||||
|
* changed in the same transaction */
|
||||||
|
m_ModifiedAttributes.insert(make_pair(name, oldValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
Value DynamicObject::InternalGetAttribute(const String& name) const
|
Value DynamicObject::InternalGetAttribute(const String& name) const
|
||||||
|
@ -454,6 +465,10 @@ void DynamicObject::BeginTx(void)
|
||||||
|
|
||||||
void DynamicObject::FinishTx(void)
|
void DynamicObject::FinishTx(void)
|
||||||
{
|
{
|
||||||
|
BOOST_FOREACH(DynamicObject *object, m_ModifiedObjects) {
|
||||||
|
object->SendLocalUpdateEvents();
|
||||||
|
}
|
||||||
|
|
||||||
OnTransactionClosing(m_ModifiedObjects);
|
OnTransactionClosing(m_ModifiedObjects);
|
||||||
m_ModifiedObjects.clear();
|
m_ModifiedObjects.clear();
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
typedef AttributeMap::const_iterator AttributeConstIterator;
|
typedef AttributeMap::const_iterator AttributeConstIterator;
|
||||||
|
|
||||||
DynamicObject(const Dictionary::Ptr& serializedObject);
|
DynamicObject(const Dictionary::Ptr& serializedObject);
|
||||||
|
~DynamicObject(void);
|
||||||
|
|
||||||
Dictionary::Ptr BuildUpdate(double sinceTx, int attributeTypes) const;
|
Dictionary::Ptr BuildUpdate(double sinceTx, int attributeTypes) const;
|
||||||
void ApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes);
|
void ApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes);
|
||||||
|
@ -95,7 +96,7 @@ public:
|
||||||
|
|
||||||
static boost::signal<void (const DynamicObject::Ptr&)> OnRegistered;
|
static boost::signal<void (const DynamicObject::Ptr&)> OnRegistered;
|
||||||
static boost::signal<void (const DynamicObject::Ptr&)> OnUnregistered;
|
static boost::signal<void (const DynamicObject::Ptr&)> OnUnregistered;
|
||||||
static boost::signal<void (const set<DynamicObject::Ptr>&)> OnTransactionClosing;
|
static boost::signal<void (const set<DynamicObject *>&)> OnTransactionClosing;
|
||||||
|
|
||||||
ScriptTask::Ptr InvokeMethod(const String& method,
|
ScriptTask::Ptr InvokeMethod(const String& method,
|
||||||
const vector<Value>& arguments, ScriptTask::CompletionCallback callback);
|
const vector<Value>& arguments, ScriptTask::CompletionCallback callback);
|
||||||
|
@ -135,17 +136,19 @@ protected:
|
||||||
virtual void OnInitCompleted(void);
|
virtual void OnInitCompleted(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InternalSetAttribute(const String& name, const Value& data, double tx, bool suppressEvent = false, bool allowEditConfig = false);
|
void InternalSetAttribute(const String& name, const Value& data, double tx, bool allowEditConfig = false);
|
||||||
Value InternalGetAttribute(const String& name) const;
|
Value InternalGetAttribute(const String& name) const;
|
||||||
|
void SendLocalUpdateEvents(void);
|
||||||
|
|
||||||
AttributeMap m_Attributes;
|
AttributeMap m_Attributes;
|
||||||
|
map<String, Value, string_iless> m_ModifiedAttributes;
|
||||||
double m_ConfigTx;
|
double m_ConfigTx;
|
||||||
|
|
||||||
static double m_CurrentTx;
|
static double m_CurrentTx;
|
||||||
|
|
||||||
static set<DynamicObject::Ptr> m_ModifiedObjects;
|
/* This has to be a set of raw pointers because the DynamicObject
|
||||||
|
* constructor has to be able to insert objects into this list. */
|
||||||
void InternalApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes, bool suppressEvents);
|
static set<DynamicObject *> m_ModifiedObjects;
|
||||||
|
|
||||||
friend class DynamicType; /* for OnInitCompleted */
|
friend class DynamicType; /* for OnInitCompleted */
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,7 @@ void Host::OnInitCompleted(void)
|
||||||
HostGroup::InvalidateMembersCache();
|
HostGroup::InvalidateMembersCache();
|
||||||
DowntimeProcessor::InvalidateDowntimeCache();
|
DowntimeProcessor::InvalidateDowntimeCache();
|
||||||
|
|
||||||
Event::Post(boost::bind(&Host::UpdateSlaveServices, this));
|
UpdateSlaveServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
Host::~Host(void)
|
Host::~Host(void)
|
||||||
|
|
Loading…
Reference in New Issue