mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-02 23:25:53 +08:00
Ref T121, check if Internet is accessible
* in case the internet provider is down, this is not detected * extended test to detect if access is possible * in case of downtime this indicated in status component
This commit is contained in:
committed by
Mathew Sutcliffe
parent
b70fb70d60
commit
f3847bd33c
@@ -140,21 +140,24 @@ namespace BlackCore
|
||||
|
||||
// Init network
|
||||
Q_ASSERT_X(m_accessManager, Q_FUNC_INFO, "Need QAM");
|
||||
m_internetAccessTimer.setObjectName("Application::m_internetAccessTimer");
|
||||
this->m_cookieManager.setParent(this->m_accessManager);
|
||||
this->m_accessManager->setCookieJar(&this->m_cookieManager);
|
||||
connect(this->m_accessManager, &QNetworkAccessManager::networkAccessibleChanged, this, &CApplication::ps_networkAccessibleChanged);
|
||||
connect(this->m_accessManager, &QNetworkAccessManager::networkAccessibleChanged, this, &CApplication::networkAccessibleChanged, Qt::QueuedConnection);
|
||||
connect(&this->m_internetAccessTimer, &QTimer::timeout, this, [this] { this->checkInternetAccessible(true); });
|
||||
CLogMessage::preformatted(CNetworkUtils::createNetworkReport(this->m_accessManager));
|
||||
this->checkInternetAccessible();
|
||||
|
||||
// global setup
|
||||
sApp = this;
|
||||
this->m_setupReader.reset(new CSetupReader(this));
|
||||
connect(this->m_setupReader.data(), &CSetupReader::setupHandlingCompleted, this, &CApplication::ps_setupHandlingCompleted);
|
||||
connect(this->m_setupReader.data(), &CSetupReader::setupHandlingCompleted, this, &CApplication::setupHandlingIsCompleted);
|
||||
connect(this->m_setupReader.data(), &CSetupReader::distributionInfoAvailable, this, &CApplication::distributionInfoAvailable);
|
||||
|
||||
this->m_parser.addOptions(this->m_setupReader->getCmdLineOptions()); // add options from reader
|
||||
|
||||
// startup done
|
||||
connect(this, &CApplication::startUpCompleted, this, &CApplication::ps_startupCompleted);
|
||||
connect(this, &CApplication::startUpCompleted, this, &CApplication::startupCompleted);
|
||||
|
||||
// notify when app goes down
|
||||
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &CApplication::gracefulShutdown);
|
||||
@@ -336,11 +339,11 @@ namespace BlackCore
|
||||
{
|
||||
QTimer::singleShot(10 * 1000, [ = ]
|
||||
{
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
CRASHPAD_SIMULATE_CRASH();
|
||||
#else
|
||||
#else
|
||||
CLogMessage(this).warning("This compiler or platform does not support crashpad. Cannot simulate crash dump!");
|
||||
#endif
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
@@ -494,6 +497,40 @@ namespace BlackCore
|
||||
return false;
|
||||
}
|
||||
|
||||
void CApplication::checkInternetAccessible(bool logWarning)
|
||||
{
|
||||
if (this->isShuttingDown()) { return; }
|
||||
|
||||
bool access = false;
|
||||
if (this->isNetworkAccessible())
|
||||
{
|
||||
QString message1;
|
||||
static const QString testHost1("www.google.com"); // what else?
|
||||
access = CNetworkUtils::canConnect(testHost1, 443, message1);
|
||||
if (!access)
|
||||
{
|
||||
QString message2;
|
||||
static const QString testHost2("www.microsoft.com"); // secondary test
|
||||
access = CNetworkUtils::canConnect(testHost2, 80, message2);
|
||||
if (!access && logWarning) { CLogMessage(this).warning("Internet access problems: %1 based on testing '%2'") << message1 << testHost1; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logWarning) { CLogMessage(this).warning("No network access"); }
|
||||
}
|
||||
|
||||
if (m_internetAccessible != access)
|
||||
{
|
||||
m_internetAccessible = access;
|
||||
emit this->internetAccessibleChanged(access);
|
||||
}
|
||||
|
||||
constexpr int checkAgainSuccess = 60 * 1000;
|
||||
constexpr int checkAgainFailure = 30 * 1000;
|
||||
m_internetAccessTimer.start(access ? checkAgainSuccess : checkAgainFailure);
|
||||
}
|
||||
|
||||
void CApplication::setSignalStartupAutomatically(bool enabled)
|
||||
{
|
||||
this->m_signalStartup = enabled;
|
||||
@@ -630,10 +667,15 @@ namespace BlackCore
|
||||
const QNetworkAccessManager::NetworkAccessibility a = this->m_accessManager->networkAccessible();
|
||||
if (a == QNetworkAccessManager::Accessible) { return true; }
|
||||
|
||||
// currently I also accept unknown
|
||||
// currently I also accept unknown because of that issue with Network Manager
|
||||
return a == QNetworkAccessManager::UnknownAccessibility;
|
||||
}
|
||||
|
||||
bool CApplication::isInternetAccessible() const
|
||||
{
|
||||
return this->isNetworkAccessible() && m_internetAccessible;
|
||||
}
|
||||
|
||||
bool CApplication::hasSetupReader() const
|
||||
{
|
||||
// m_startSetupReader set to false, if something wrong with parsing
|
||||
@@ -855,7 +897,7 @@ namespace BlackCore
|
||||
this->m_fileLogger->close();
|
||||
}
|
||||
|
||||
void CApplication::ps_setupHandlingCompleted(bool available)
|
||||
void CApplication::setupHandlingIsCompleted(bool available)
|
||||
{
|
||||
if (available)
|
||||
{
|
||||
@@ -872,12 +914,12 @@ namespace BlackCore
|
||||
}
|
||||
}
|
||||
|
||||
void CApplication::ps_startupCompleted()
|
||||
void CApplication::startupCompleted()
|
||||
{
|
||||
// void
|
||||
}
|
||||
|
||||
void CApplication::ps_networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible)
|
||||
void CApplication::networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible)
|
||||
{
|
||||
switch (accessible)
|
||||
{
|
||||
@@ -892,6 +934,7 @@ namespace BlackCore
|
||||
CLogMessage(this).warning("Network accessibility unknown");
|
||||
break;
|
||||
}
|
||||
this->checkInternetAccessible();
|
||||
}
|
||||
|
||||
CStatusMessageList CApplication::asyncWebAndContextStart()
|
||||
|
||||
@@ -159,6 +159,9 @@ namespace BlackCore
|
||||
//! Network accessible?
|
||||
bool isNetworkAccessible() const;
|
||||
|
||||
//! Internet accessible?
|
||||
bool isInternetAccessible() const;
|
||||
|
||||
//! Access to access manager
|
||||
const QNetworkAccessManager *getNetworkAccessManager() const { return m_accessManager; }
|
||||
|
||||
@@ -408,17 +411,19 @@ namespace BlackCore
|
||||
//! Web data services started
|
||||
void webDataServicesStarted(bool success);
|
||||
|
||||
protected slots:
|
||||
//! Setup read/synchronized
|
||||
void ps_setupHandlingCompleted(bool available);
|
||||
|
||||
//! Startup completed
|
||||
virtual void ps_startupCompleted();
|
||||
|
||||
//! Problem with network access manager
|
||||
virtual void ps_networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible);
|
||||
//! Internet accessinility changed
|
||||
void internetAccessibleChanged(bool access);
|
||||
|
||||
protected:
|
||||
//! Setup read/synchronized
|
||||
void setupHandlingIsCompleted(bool available);
|
||||
|
||||
//! Startup completed
|
||||
virtual void startupCompleted();
|
||||
|
||||
//! Problem with network access manager
|
||||
virtual void networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible);
|
||||
|
||||
//! Init class, allows to init from BlackGui::CGuiApplication as well (pseudo virtual)
|
||||
void init(bool withMetadata);
|
||||
|
||||
@@ -480,6 +485,9 @@ namespace BlackCore
|
||||
//! Dev.environment
|
||||
bool initIsRunningInDeveloperEnvironment() const;
|
||||
|
||||
//! Check that Internet is accessible
|
||||
void checkInternetAccessible(bool logWarning = true);
|
||||
|
||||
//! Async. start when setup is loaded
|
||||
BlackMisc::CStatusMessageList asyncWebAndContextStart();
|
||||
|
||||
@@ -489,25 +497,27 @@ namespace BlackCore
|
||||
int maxRedirects,
|
||||
std::function<QNetworkReply *(QNetworkAccessManager &, const QNetworkRequest &)> requestOrPostMethod);
|
||||
|
||||
QNetworkAccessManager *m_accessManager = nullptr; //!< single network access manager
|
||||
QNetworkAccessManager *m_accessManager = nullptr; //!< single network access manager
|
||||
BlackMisc::CApplicationInfo::Application m_application = BlackMisc::CApplicationInfo::Unknown; //!< Application if specified
|
||||
QScopedPointer<CCoreFacade> m_coreFacade; //!< core facade if any
|
||||
QScopedPointer<CSetupReader> m_setupReader; //!< setup reader
|
||||
QScopedPointer<CWebDataServices> m_webDataServices; //!< web data services
|
||||
QScopedPointer<BlackMisc::CFileLogger> m_fileLogger; //!< file logger
|
||||
CCookieManager m_cookieManager; //!< single cookie manager for our access manager
|
||||
QString m_applicationName; //!< application name
|
||||
QReadWriteLock m_accessManagerLock; //!< lock to make access manager access threadsafe
|
||||
CCoreFacadeConfig m_coreFacadeConfig; //!< Core facade config if any
|
||||
CWebReaderFlags::WebReader m_webReadersUsed; //!< Readers to be used
|
||||
BlackCore::Db::CDatabaseReaderConfigList m_dbReaderConfig; //!< Load or used caching?
|
||||
std::atomic<bool> m_shutdown { false }; //!< is being shutdown?
|
||||
bool m_useContexts = false; //!< use contexts
|
||||
bool m_useWebData = false; //!< use web data
|
||||
bool m_signalStartup = true; //!< signal startup automatically
|
||||
bool m_devEnv = false; //!< dev. environment
|
||||
bool m_unitTest = false; //!< is UNIT test
|
||||
bool m_autoSaveSettings = true;//!< automatically saving all settings
|
||||
QScopedPointer<CCoreFacade> m_coreFacade; //!< core facade if any
|
||||
QScopedPointer<CSetupReader> m_setupReader; //!< setup reader
|
||||
QScopedPointer<CWebDataServices> m_webDataServices; //!< web data services
|
||||
QScopedPointer<BlackMisc::CFileLogger> m_fileLogger; //!< file logger
|
||||
CCookieManager m_cookieManager; //!< single cookie manager for our access manager
|
||||
QString m_applicationName; //!< application name
|
||||
QReadWriteLock m_accessManagerLock; //!< lock to make access manager access threadsafe
|
||||
CCoreFacadeConfig m_coreFacadeConfig; //!< Core facade config if any
|
||||
CWebReaderFlags::WebReader m_webReadersUsed; //!< Readers to be used
|
||||
BlackCore::Db::CDatabaseReaderConfigList m_dbReaderConfig; //!< Load or used caching?
|
||||
std::atomic<bool> m_shutdown { false }; //!< is being shutdown?
|
||||
QTimer m_internetAccessTimer { this };
|
||||
bool m_useContexts = false; //!< use contexts
|
||||
bool m_useWebData = false; //!< use web data
|
||||
bool m_signalStartup = true; //!< signal startup automatically
|
||||
bool m_devEnv = false; //!< dev. environment
|
||||
bool m_unitTest = false; //!< is UNIT test
|
||||
bool m_autoSaveSettings = true; //!< automatically saving all settings
|
||||
bool m_internetAccessible = true; //!< Internet accessible
|
||||
|
||||
// -------------- crashpad -----------------
|
||||
BlackMisc::CStatusMessageList initCrashHandler();
|
||||
|
||||
@@ -203,7 +203,7 @@ namespace BlackCore
|
||||
this->threadAssertCheck();
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
entity &= CEntityFlags::AirportEntity;
|
||||
if (!this->isNetworkAccessible())
|
||||
if (!this->isInternetAccessible())
|
||||
{
|
||||
emit this->dataRead(entity, CEntityFlags::ReadSkipped, 0);
|
||||
return;
|
||||
|
||||
@@ -198,7 +198,7 @@ namespace BlackCore
|
||||
|
||||
// ps_read is implemented in the derived classes
|
||||
if (entities == CEntityFlags::NoEntity) { return; }
|
||||
if (!this->isNetworkAccessible(QString("No network, will not read %1").arg(CEntityFlags::flagToString(entities)))) { return; }
|
||||
if (!this->isInternetAccessible(QString("No network/internet access, will not read %1").arg(CEntityFlags::flagToString(entities)))) { return; }
|
||||
|
||||
const bool s = QMetaObject::invokeMethod(this, "ps_read",
|
||||
Q_ARG(BlackMisc::Network::CEntityFlags::Entity, entities),
|
||||
@@ -370,7 +370,7 @@ namespace BlackCore
|
||||
|
||||
bool CDatabaseReader::requestHeadersOfSharedFiles(CEntityFlags::Entity entities)
|
||||
{
|
||||
if (!this->isNetworkAccessible(QString("No network, will not read shared file headers for %1").arg(CEntityFlags::flagToString(entities)))) { return false; }
|
||||
if (!this->isInternetAccessible(QString("No network/internet access, will not read shared file headers for %1").arg(CEntityFlags::flagToString(entities)))) { return false; }
|
||||
|
||||
CEntityFlags::Entity allEntities(this->maskBySupportedEntities(entities));
|
||||
CEntityFlags::Entity currentEntity = CEntityFlags::iterateDbEntities(allEntities);
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace BlackCore
|
||||
this->threadAssertCheck(); // runs in background thread
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
entities &= CEntityFlags::AllIcaoAndCountries;
|
||||
if (!this->isNetworkAccessible())
|
||||
if (!this->isInternetAccessible())
|
||||
{
|
||||
emit this->dataRead(entities, CEntityFlags::ReadSkipped, 0);
|
||||
return;
|
||||
|
||||
@@ -95,6 +95,7 @@ namespace BlackCore
|
||||
|
||||
void CInfoDataReader::read()
|
||||
{
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
const CUrl url(this->getInfoObjectsUrl());
|
||||
if (!url.isEmpty())
|
||||
{
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace BlackCore
|
||||
this->threadAssertCheck();
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
entities &= CEntityFlags::DistributorLiveryModel;
|
||||
if (!this->isNetworkAccessible())
|
||||
if (!this->isInternetAccessible())
|
||||
{
|
||||
emit this->dataRead(entities, CEntityFlags::ReadSkipped, 0);
|
||||
return;
|
||||
|
||||
@@ -208,9 +208,9 @@ namespace BlackCore
|
||||
CStatusMessageList CSetupReader::triggerReadSetup()
|
||||
{
|
||||
if (this->m_shutdown) { return CStatusMessage(this, CStatusMessage::SeverityError, "shutdown"); }
|
||||
if (!sApp->isNetworkAccessible())
|
||||
if (!sApp->isInternetAccessible())
|
||||
{
|
||||
const CStatusMessage m(this, CStatusMessage::SeverityInfo, "No network, will try to recover");
|
||||
const CStatusMessage m(this, CStatusMessage::SeverityInfo, "No network/internet, will try to recover");
|
||||
CStatusMessageList msgs(m);
|
||||
msgs.push_back(this->manageSetupAvailability(false, false));
|
||||
this->setLastSetupReadErrorMessages(msgs);
|
||||
|
||||
@@ -68,9 +68,9 @@ namespace BlackCore
|
||||
return delta <= timeLastMs;
|
||||
}
|
||||
|
||||
bool CThreadedReader::isNetworkAccessible(const QString &logWarningMessage) const
|
||||
bool CThreadedReader::isInternetAccessible(const QString &logWarningMessage) const
|
||||
{
|
||||
const bool a = sApp->isNetworkAccessible();
|
||||
const bool a = sApp->isInternetAccessible();
|
||||
if (!a && !logWarningMessage.isEmpty())
|
||||
{
|
||||
CLogMessage(this).warning(logWarningMessage);
|
||||
@@ -148,6 +148,7 @@ namespace BlackCore
|
||||
{
|
||||
if (!m_unitTest && (!sApp || !sApp->hasWebDataServices())) { return false; }
|
||||
if (!isEnabled()) { return false; }
|
||||
if (isAbandoned()) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace BlackCore
|
||||
|
||||
//! Network accessible?
|
||||
//! \param logWarningMessage optional warning if not accessible
|
||||
bool isNetworkAccessible(const QString &logWarningMessage = {}) const;
|
||||
bool isInternetAccessible(const QString &logWarningMessage = {}) const;
|
||||
|
||||
//! Is marked as read failed
|
||||
//! \threadsafe
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace BlackCore
|
||||
{
|
||||
this->threadAssertCheck();
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
if (!this->isNetworkAccessible("No network, cannot read VATSIM bookings")) { return; }
|
||||
if (!this->isInternetAccessible("No network/internet access, cannot read VATSIM bookings")) { return; }
|
||||
|
||||
Q_ASSERT_X(sApp, Q_FUNC_INFO, "No application");
|
||||
const QUrl url(sApp->getGlobalSetup().getVatsimBookingsUrl());
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace BlackCore
|
||||
{
|
||||
this->threadAssertCheck();
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
if (!this->isNetworkAccessible("No network, cannot read VATSIM data file")) { return; }
|
||||
if (!this->isInternetAccessible("No network/internet access, cannot read VATSIM data file")) { return; }
|
||||
|
||||
// round robin for load balancing
|
||||
// remark: Don't use QThread to run network operations in the background
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace BlackCore
|
||||
{
|
||||
this->threadAssertCheck();
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
if (!this->isNetworkAccessible("No network, cannot read METARs")) { return; }
|
||||
if (!this->isInternetAccessible("No network/internet access, cannot read METARs")) { return; }
|
||||
|
||||
CFailoverUrlList urls(sApp->getVatsimMetarUrls());
|
||||
const CUrl url(urls.obtainNextWorkingUrl(true));
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace BlackCore
|
||||
{
|
||||
this->threadAssertCheck();
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
if (!this->isNetworkAccessible("No network, cannot read VATSIM status file")) { return; }
|
||||
if (!this->isInternetAccessible("No network/internet access, cannot read VATSIM status file")) { return; }
|
||||
|
||||
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing application");
|
||||
CFailoverUrlList urls(sApp->getGlobalSetup().getVatsimStatusFileUrls());
|
||||
|
||||
@@ -928,7 +928,14 @@ namespace BlackCore
|
||||
}
|
||||
|
||||
// and trigger read
|
||||
QTimer::singleShot(0, m_dbInfoDataReader, [this]() { this->m_dbInfoDataReader->read(); });
|
||||
if (sApp->isInternetAccessible())
|
||||
{
|
||||
QTimer::singleShot(0, m_dbInfoDataReader, [this]() { this->m_dbInfoDataReader->read(); });
|
||||
}
|
||||
else
|
||||
{
|
||||
CLogMessage(this).warning("No network/internet access, skipping read of info objects");
|
||||
}
|
||||
}
|
||||
|
||||
void CWebDataServices::initSharedInfoObjectReaderAndTriggerRead()
|
||||
@@ -956,7 +963,14 @@ namespace BlackCore
|
||||
}
|
||||
|
||||
// and trigger read
|
||||
QTimer::singleShot(0, m_sharedInfoDataReader, [this]() { this->m_sharedInfoDataReader->read(); });
|
||||
if (sApp->isInternetAccessible())
|
||||
{
|
||||
QTimer::singleShot(0, m_sharedInfoDataReader, [this]() { this->m_sharedInfoDataReader->read(); });
|
||||
}
|
||||
else
|
||||
{
|
||||
CLogMessage(this).warning("No network/internet access, skipping read of shared data");
|
||||
}
|
||||
}
|
||||
|
||||
CDatabaseReader *CWebDataServices::getDbReader(CEntityFlags::Entity entity) const
|
||||
|
||||
Reference in New Issue
Block a user