From 378894d24f6d1764019f7c733cf2aeee021e43f5 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sun, 5 Aug 2012 03:10:53 +0200 Subject: [PATCH] Fixed restoring the program state. --- base/dynamicobject.cpp | 72 +++++------------------------------- base/dynamicobject.h | 3 -- icinga/icingaapplication.cpp | 18 ++++----- 3 files changed, 18 insertions(+), 75 deletions(-) diff --git a/base/dynamicobject.cpp b/base/dynamicobject.cpp index 4ba36c124..d6970f09b 100644 --- a/base/dynamicobject.cpp +++ b/base/dynamicobject.cpp @@ -423,25 +423,21 @@ void DynamicObject::RestoreObjects(const String& filename) String message; while (NetString::ReadStringFromIOQueue(fifo.get(), &message)) { - Value value = Value::Deserialize(message); - - if (!value.IsObjectType()) - throw_exception(runtime_error("JSON objects in the program state file must be dictionaries.")); - - Dictionary::Ptr persistentObject = value; + Dictionary::Ptr persistentObject = Value::Deserialize(message); String type = persistentObject->Get("type"); String name = persistentObject->Get("name"); - bool hasConfig = persistentObject->Contains("configTx"); Dictionary::Ptr update = persistentObject->Get("update"); - if (hasConfig && ClassExists(type)) { - DynamicObject::Ptr object = Create(type, update); + bool hasConfig = update->Contains("configTx"); + + DynamicObject::Ptr object = GetObject(type, name); + + if (hasConfig && !object) { + object = Create(type, update); object->Register(); - } else { - /* keep non-replicated objects until another config object with - * the same name is created (which is when we restore its tags) */ - GetPersistentObjects()[make_pair(type, name)] = update; + } else if (object) { + object->ApplyUpdate(update, Attribute_All); } } } @@ -458,13 +454,6 @@ DynamicObject::ClassMap& DynamicObject::GetClasses(void) return classes; } -DynamicObject::PersistentUpdateMap& DynamicObject::GetPersistentObjects(void) -{ - static DynamicObject::PersistentUpdateMap persistentObjects; - return persistentObjects; -} - - void DynamicObject::RegisterClass(const String& type, DynamicObject::Factory factory) { if (GetObjects(type).first != GetObjects(type).second) @@ -472,37 +461,6 @@ void DynamicObject::RegisterClass(const String& type, DynamicObject::Factory fac type + "': Objects of this type already exist.")); GetClasses()[type] = factory; - - /* restore persistent objects that match the newly-registered class */ - map, Dictionary::Ptr>::iterator prev, st; - for (st = GetPersistentObjects().begin(); st != GetPersistentObjects().end(); ) - { - /* check type of the update */ - if (st->first.first != type) { - st++; - continue; - } - - Dictionary::Ptr update = st->second; - bool hasConfig = update->Contains("configTx"); - if (!hasConfig) { - st++; - continue; - } - - DynamicObject::Ptr object = Create(type, update); - object->Register(); - - prev = st; - st++; - GetPersistentObjects().erase(prev); - } - -} - -bool DynamicObject::ClassExists(const String& type) -{ - return (GetClasses().find(type) != GetClasses().end()); } DynamicObject::Ptr DynamicObject::Create(const String& type, const Dictionary::Ptr& serializedUpdate) @@ -519,18 +477,6 @@ DynamicObject::Ptr DynamicObject::Create(const String& type, const Dictionary::P Logger::Write(LogCritical, "base", "Creating generic DynamicObject for type '" + type + "'"); } - /* restore the object's persistent non-config attributes */ - map, Dictionary::Ptr>::iterator st; - st = GetPersistentObjects().find(make_pair(obj->GetType(), obj->GetName())); - if (st != GetPersistentObjects().end()) { - Logger::Write(LogDebug, "base", "Restoring persistent state " - "for object " + obj->GetType() + ":" + obj->GetName()); - obj->ApplyUpdate(st->second, Attribute_All & ~Attribute_Config); - - /* we're done with this update, remove it */ - GetPersistentObjects().erase(st); - } - /* apply the object's non-config attributes */ obj->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config); diff --git a/base/dynamicobject.h b/base/dynamicobject.h index 042e61630..9856e9b79 100644 --- a/base/dynamicobject.h +++ b/base/dynamicobject.h @@ -140,9 +140,6 @@ private: static double m_CurrentTx; - typedef map, Dictionary::Ptr> PersistentUpdateMap; - static PersistentUpdateMap& GetPersistentObjects(void); - static set m_ModifiedObjects; void InternalApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes, bool suppressEvents); diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index bbe451ae4..d8d829999 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -50,15 +50,6 @@ int IcingaApplication::Main(const vector& args) consoleLogConfig->Compile()->Commit(); consoleLogConfig.reset(); - /* restore the previous program state */ - DynamicObject::RestoreObjects("retention.dat"); - - /* periodically dump the program state */ - m_RetentionTimer = boost::make_shared(); - m_RetentionTimer->SetInterval(60); - m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this)); - m_RetentionTimer->Start(); - #ifdef _WIN32 Logger::Write(LogInformation, "icinga", "Icinga component loader"); #else /* _WIN32 */ @@ -193,6 +184,15 @@ int IcingaApplication::Main(const vector& args) UpdatePidFile(GetPidPath()); } + /* restore the previous program state */ + DynamicObject::RestoreObjects("retention.dat"); + + /* periodically dump the program state */ + m_RetentionTimer = boost::make_shared(); + m_RetentionTimer->SetInterval(300); + m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this)); + m_RetentionTimer->Start(); + RunEventLoop(); DumpProgramState(); -- 2.40.0