refs #846, improved start and waitForSetup

* directly wait for setup after triggering read
* use more detailed status messages
* in case of severe issues directly stop application
This commit is contained in:
Klaus Basan
2016-12-29 01:16:27 +01:00
committed by Mathew Sutcliffe
parent 83dad62d4b
commit 235673123d
2 changed files with 77 additions and 52 deletions

View File

@@ -233,72 +233,97 @@ namespace BlackCore
return r->getUpdateInfo(); return r->getUpdateInfo();
} }
bool CApplication::start(bool waitForStart) bool CApplication::start()
{ {
// parse if needed, parsing contains its own error handling
if (!this->m_parsed) if (!this->m_parsed)
{ {
bool s = this->parse(); bool s = this->parse();
if (!s) { return false; } if (!s) { return false; }
} }
// parsing itself is done
CStatusMessageList msgs;
do
{
// clear cache? // clear cache?
if (this->isSetOrTrue(this->m_cmdClearCache)) if (this->isSetOrTrue(this->m_cmdClearCache))
{ {
QStringList files(CApplication::clearCaches()); const QStringList files(CApplication::clearCaches());
CLogMessage(this).debug() << "Cleared cache, " << files.size() << " files"; msgs.push_back(
CLogMessage(this).debug() << "Cleared cache, " << files.size() << " files"
);
} }
// parsing itself is done
if (this->m_startSetupReader && !this->m_setupReader->isSetupAvailable()) if (this->m_startSetupReader && !this->m_setupReader->isSetupAvailable())
{ {
const CStatusMessageList msgs(this->requestReloadOfSetupAndVersion()); msgs = this->requestReloadOfSetupAndVersion();
CLogMessage::preformatted(msgs); if (msgs.isSuccess())
if (msgs.isFailure())
{ {
this->cmdLineErrorMessage(msgs.getWarningAndErrorMessages().toSingleMessage().getMessage()); msgs.push_back(this->waitForSetup());
return false;
} }
if (msgs.isFailure()) { break; }
} }
bool s = this->startHookIn(); // start hookin
msgs.push_back(this->startHookIn());
if (msgs.isFailure()) { break; }
// trigger loading and saving of settings in appropriate scenarios // trigger loading and saving of settings in appropriate scenarios
if (this->m_coreFacadeConfig.getModeApplication() != CCoreFacadeConfig::Remote) if (this->m_coreFacadeConfig.getModeApplication() != CCoreFacadeConfig::Remote)
{ {
CStatusMessage m = CSettingsCache::instance()->loadFromStore(); // facade running here locally
if (!m.isEmpty()) msgs.push_back(CSettingsCache::instance()->loadFromStore());
{ if (msgs.isFailure()) { break; }
m.setCategories(getLogCategories());
CLogMessage::preformatted(m);
}
// Settings are distributed via DBus. So only one application is responsible for saving. `enableLocalSave()` means // Settings are distributed via DBus. So only one application is responsible for saving. `enableLocalSave()` means
// "this is the application responsible for saving". If swiftgui requests a setting to be saved, it is sent to swiftcore and saved by swiftcore. // "this is the application responsible for saving". If swiftgui requests a setting to be saved, it is sent to swiftcore and saved by swiftcore.
CSettingsCache::instance()->enableLocalSave(); CSettingsCache::instance()->enableLocalSave();
// From this moment on, we have settings, so enable crash handler. // From this moment on, we have settings, so enable crash handler.
initCrashHandler(); msgs.push_back(this->initCrashHandler());
} }
}
while (false);
if (waitForStart) // terminate with failures, otherwise log messages
if (msgs.isFailure())
{ {
s = this->waitForStart(); this->cmdLineErrorMessage(msgs);
return false;
} }
this->m_started = s; else if (!msgs.isEmpty())
return s; {
CLogMessage::preformatted(msgs);
} }
bool CApplication::waitForStart() this->m_started = true;
return this->m_started;
}
CStatusMessageList CApplication::waitForSetup()
{
if (!this->m_setupReader) { return CStatusMessage(this).error("No setup reader"); }
if (!this->m_setupReader->isSetupAvailable())
{ {
QEventLoop eventLoop; QEventLoop eventLoop;
QTimer::singleShot(5000, &eventLoop, &QEventLoop::quit); QTimer::singleShot(5000, &eventLoop, &QEventLoop::quit);
connect(this, &CApplication::setupAvailable, &eventLoop, &QEventLoop::quit); connect(this, &CApplication::setupHandlingCompleted, &eventLoop, &QEventLoop::quit);
eventLoop.exec(); eventLoop.exec();
if (!this->m_startUpCompleted)
{
CLogMessage(this).error("Waiting for startup timed out");
} }
return this->m_started;
// setup handling completed with success or failure, or we run into time out
if (this->m_setupReader->isSetupAvailable()) { return CStatusMessage(this).info("Setup available"); }
CStatusMessageList msgs(CStatusMessage(this).error("Setup not available, setup reading failed or timed out."));
if (this->m_setupReader->getLastSetupReadErrorMessages().hasErrorMessages())
{
msgs.push_back(this->m_setupReader->getLastSetupReadErrorMessages());
}
if (this->m_setupReader->hasCmdLineBootstrapUrl())
{
msgs.push_back(CStatusMessage(this).info("Check cmd line argument '%1'") << this->m_setupReader->getCmdLineBootstrapUrl());
}
return msgs;
} }
bool CApplication::isSetupAvailable() const bool CApplication::isSetupAvailable() const

View File

@@ -307,10 +307,10 @@ namespace BlackCore
virtual void gracefulShutdown(); virtual void gracefulShutdown();
//! Start services, if not yet parsed call CApplication::parse //! Start services, if not yet parsed call CApplication::parse
virtual bool start(bool waitForStart = true); virtual bool start();
//! Wait for stert by calling the event loop and waiting until everything is ready //! Wait for setup data by calling the event loop and waiting until everything is ready
bool waitForStart(); BlackMisc::CStatusMessageList waitForSetup();
//! Request to get network reply //! Request to get network reply
//! \threadsafe //! \threadsafe