Fixed restoring the program state.

This commit is contained in:
Gunnar Beutner 2012-08-05 03:10:53 +02:00
parent 2f7b67ce2b
commit 378894d24f
3 changed files with 18 additions and 75 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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();