mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-12 16:24:41 +02:00
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;
|
String message;
|
||||||
while (NetString::ReadStringFromIOQueue(fifo.get(), &message)) {
|
while (NetString::ReadStringFromIOQueue(fifo.get(), &message)) {
|
||||||
Value value = Value::Deserialize(message);
|
Dictionary::Ptr persistentObject = 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;
|
|
||||||
|
|
||||||
String type = persistentObject->Get("type");
|
String type = persistentObject->Get("type");
|
||||||
String name = persistentObject->Get("name");
|
String name = persistentObject->Get("name");
|
||||||
bool hasConfig = persistentObject->Contains("configTx");
|
|
||||||
Dictionary::Ptr update = persistentObject->Get("update");
|
Dictionary::Ptr update = persistentObject->Get("update");
|
||||||
|
|
||||||
if (hasConfig && ClassExists(type)) {
|
bool hasConfig = update->Contains("configTx");
|
||||||
DynamicObject::Ptr object = Create(type, update);
|
|
||||||
|
DynamicObject::Ptr object = GetObject(type, name);
|
||||||
|
|
||||||
|
if (hasConfig && !object) {
|
||||||
|
object = Create(type, update);
|
||||||
object->Register();
|
object->Register();
|
||||||
} else {
|
} else if (object) {
|
||||||
/* keep non-replicated objects until another config object with
|
object->ApplyUpdate(update, Attribute_All);
|
||||||
* the same name is created (which is when we restore its tags) */
|
|
||||||
GetPersistentObjects()[make_pair(type, name)] = update;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -458,13 +454,6 @@ DynamicObject::ClassMap& DynamicObject::GetClasses(void)
|
|||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicObject::PersistentUpdateMap& DynamicObject::GetPersistentObjects(void)
|
|
||||||
{
|
|
||||||
static DynamicObject::PersistentUpdateMap persistentObjects;
|
|
||||||
return persistentObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DynamicObject::RegisterClass(const String& type, DynamicObject::Factory factory)
|
void DynamicObject::RegisterClass(const String& type, DynamicObject::Factory factory)
|
||||||
{
|
{
|
||||||
if (GetObjects(type).first != GetObjects(type).second)
|
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."));
|
type + "': Objects of this type already exist."));
|
||||||
|
|
||||||
GetClasses()[type] = factory;
|
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)
|
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 + "'");
|
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 */
|
/* apply the object's non-config attributes */
|
||||||
obj->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
|
obj->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
|
||||||
|
|
||||||
|
@ -140,9 +140,6 @@ private:
|
|||||||
|
|
||||||
static double m_CurrentTx;
|
static double m_CurrentTx;
|
||||||
|
|
||||||
typedef map<pair<String, String>, Dictionary::Ptr> PersistentUpdateMap;
|
|
||||||
static PersistentUpdateMap& GetPersistentObjects(void);
|
|
||||||
|
|
||||||
static set<DynamicObject::Ptr> m_ModifiedObjects;
|
static set<DynamicObject::Ptr> m_ModifiedObjects;
|
||||||
|
|
||||||
void InternalApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes, bool suppressEvents);
|
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->Compile()->Commit();
|
||||||
consoleLogConfig.reset();
|
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
|
#ifdef _WIN32
|
||||||
Logger::Write(LogInformation, "icinga", "Icinga component loader");
|
Logger::Write(LogInformation, "icinga", "Icinga component loader");
|
||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
@ -193,6 +184,15 @@ int IcingaApplication::Main(const vector<String>& args)
|
|||||||
UpdatePidFile(GetPidPath());
|
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();
|
RunEventLoop();
|
||||||
|
|
||||||
DumpProgramState();
|
DumpProgramState();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user