mirror of https://github.com/Icinga/icinga2.git
Fixed restoring the program state.
This commit is contained in:
parent
2f7b67ce2b
commit
378894d24f
|
@ -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<Dictionary>())
|
||||
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<pair<String, String>, 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<pair<String, String>, 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);
|
||||
|
||||
|
|
|
@ -140,9 +140,6 @@ private:
|
|||
|
||||
static double m_CurrentTx;
|
||||
|
||||
typedef map<pair<String, String>, Dictionary::Ptr> PersistentUpdateMap;
|
||||
static PersistentUpdateMap& GetPersistentObjects(void);
|
||||
|
||||
static set<DynamicObject::Ptr> m_ModifiedObjects;
|
||||
|
||||
void InternalApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes, bool suppressEvents);
|
||||
|
|
|
@ -50,15 +50,6 @@ int IcingaApplication::Main(const vector<String>& 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<Timer>();
|
||||
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<String>& args)
|
|||
UpdatePidFile(GetPidPath());
|
||||
}
|
||||
|
||||
/* restore the previous program state */
|
||||
DynamicObject::RestoreObjects("retention.dat");
|
||||
|
||||
/* periodically dump the program state */
|
||||
m_RetentionTimer = boost::make_shared<Timer>();
|
||||
m_RetentionTimer->SetInterval(300);
|
||||
m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this));
|
||||
m_RetentionTimer->Start();
|
||||
|
||||
RunEventLoop();
|
||||
|
||||
DumpProgramState();
|
||||
|
|
Loading…
Reference in New Issue