diff --git a/src/blackcore/data/globalsetup.cpp b/src/blackcore/data/globalsetup.cpp index 58db9b8c5..ab1927c8a 100644 --- a/src/blackcore/data/globalsetup.cpp +++ b/src/blackcore/data/globalsetup.cpp @@ -45,11 +45,11 @@ namespace BlackCore void CGlobalSetup::initDefaultValues() { m_mappingMinimumVersion = CBuildConfig::getVersionString(); - m_dbRootDirectoryUrl = CUrl("https://datastore.swift-project.org/"); - m_vatsimBookingsUrl = CUrl("http://vatbook.euroutepro.com/xml2.php"); - m_vatsimMetarsUrls = CUrlList({"http://metar.vatsim.net/metar.php"}); - m_vatsimStatusFileUrls = CUrlList({ "https://status.vatsim.net" }); - m_vatsimDataFileUrls = CUrlList({ "http://info.vroute.net/vatsim-data.txt" }); + m_dbRootDirectoryUrl = CUrl("https://datastore.swift-project.org/"); + m_vatsimBookingsUrl = CUrl("http://vatbook.euroutepro.com/xml2.php"); + m_vatsimMetarsUrls = CUrlList({"http://metar.vatsim.net/metar.php"}); + m_vatsimStatusFileUrls = CUrlList({ "https://status.vatsim.net" }); + m_vatsimDataFileUrls = CUrlList({ "http://info.vroute.net/vatsim-data.txt" }); m_sharedUrls = CUrlList( { "https://datastore.swift-project.net/shared/", diff --git a/src/blackcore/vatsim/vatsimstatusfilereader.cpp b/src/blackcore/vatsim/vatsimstatusfilereader.cpp index eb0a1b8c6..17777c122 100644 --- a/src/blackcore/vatsim/vatsimstatusfilereader.cpp +++ b/src/blackcore/vatsim/vatsimstatusfilereader.cpp @@ -71,10 +71,28 @@ namespace BlackCore 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()); - const CUrl url(urls.obtainNextWorkingUrl(true)); // random working URL + const CUrlList urls(sApp->getGlobalSetup().getVatsimStatusFileUrls()); + const CUrl url = urls.getRandomUrl(); if (url.isEmpty()) { return; } + CLogMessage(this).info(u"Trigger read of VATSIM status file from '%1'") << url.toQString(true); this->getFromNetworkAndLog(url, { this, &CVatsimStatusFileReader::parseVatsimFile}); + + if (urls.size() < 2) { return; } + const CUrl secondary = urls.getRandomWithout(url); + if (secondary.isEmpty()) { return; } + + constexpr int DelayMs = 5000; + const QPointer myself(this); + QTimer::singleShot(DelayMs, this, [ = ] + { + if (!myself) { return; } + const CVatsimSetup vs(m_lastGoodSetup.get()); + if (vs.getTimeDifferenceToNowMs() > 2 * DelayMs) + { + // not yet read + this->getFromNetworkAndLog(url, { this, &CVatsimStatusFileReader::parseVatsimFile}); + } + }); } void CVatsimStatusFileReader::parseVatsimFile(QNetworkReply *nwReplyPtr) @@ -93,6 +111,8 @@ namespace BlackCore } this->logNetworkReplyReceived(nwReplyPtr); + const QString urlString = nwReply->url().toString(); + if (nwReply->error() == QNetworkReply::NoError) { const QString dataFileData = nwReply->readAll(); @@ -148,12 +168,15 @@ namespace BlackCore // cache itself is thread safe, avoid writing with unchanged data CVatsimSetup vs(m_lastGoodSetup.get()); const bool changed = vs.setUrls(dataFileUrls, serverFileUrls, metarFileUrls); - if (changed) + vs.setUtcTimestamp(QDateTime::currentDateTime()); + const CStatusMessage cacheMsg = m_lastGoodSetup.set(vs); + if (cacheMsg.isFailure()) { CLogMessage::preformatted(cacheMsg); } + else { - vs.setUtcTimestamp(QDateTime::currentDateTime()); - const CStatusMessage cacheMsg = m_lastGoodSetup.set(vs); - if (cacheMsg.isFailure()) { CLogMessage::preformatted(cacheMsg); } + CLogMessage(this).info(u"Read VATSIM status file from '%1', %2 data file URLs, %3 server file URLs, %4 METAR file URLs") + << urlString << dataFileUrls.size() << serverFileUrls.size() << metarFileUrls.size(); } + Q_UNUSED(changed); // data read finished emit this->dataFileRead(lines.count()); @@ -162,7 +185,7 @@ namespace BlackCore else { // network error - CLogMessage(this).warning(u"Reading VATSIM status file failed '%1' '%2'") << nwReply->errorString() << nwReply->url().toString(); + CLogMessage(this).warning(u"Reading VATSIM status file failed '%1' '%2'") << nwReply->errorString() << urlString; nwReply->abort(); emit this->dataRead(CEntityFlags::VatsimStatusFile, CEntityFlags::ReadFailed, 0); } diff --git a/src/blackmisc/network/urllist.cpp b/src/blackmisc/network/urllist.cpp index d69666b79..d73a8dfdb 100644 --- a/src/blackmisc/network/urllist.cpp +++ b/src/blackmisc/network/urllist.cpp @@ -61,6 +61,12 @@ namespace BlackMisc return CUrl(); } + CUrl CUrlList::getRandomWithout(const CUrl &exclude) const + { + const CUrlList excludes({ exclude }); + return this->getRandomWithout(excludes); + } + CUrl CUrlList::getRandomWithout(const CUrlList &exclude) const { CUrlList copy(*this); diff --git a/src/blackmisc/network/urllist.h b/src/blackmisc/network/urllist.h index dcdc537df..23def8b6b 100644 --- a/src/blackmisc/network/urllist.h +++ b/src/blackmisc/network/urllist.h @@ -49,6 +49,9 @@ namespace BlackMisc //! Random location for distributed load, tested CUrl getRandomWorkingUrl(int maxTrials = 2, int timeoutMs = -1) const; + //! Random location for distributed load + CUrl getRandomWithout(const CUrl &exclude) const; + //! Random location for distributed load CUrl getRandomWithout(const CUrlList &exclude) const;